Origin of the problem
In the article a few days ago, we learned that the problem that has been puzzled by us for several days is that the new version of jfinal uses the undertowServer method to start, and the way of embedding filters has changed, which causes the online search to fail to embed filters.
Without considering modifying the undertowServer, it means that we need to find a way to embed shiro in the undertowServer environment.
Today, let's try a Stateless Jfinal embedding method that is implemented through an interceptor.
Stateless understanding
Personal understanding of Stateless is to separate the front and back ends, and the two requests are independent of each other, and to determine whether they are the same user through the agreed token and other content.
Therefore, this requires that the login interface needs to generate a random token for the user so that the user can bring it with him during subsequent access.
Login interface
The login interface first requires us to access the database and use a specific algorithm to verify whether the user name and password match. If it matches, a random string, that is, token, is generated and saved in redis. Note that the mapping relationship is that token is key and value is user information. It can be a user name or user ID and other user unique identifier.
@Clear public void Login() { String name = getPara("name"); String password = getPara("password"); if ("admin".equals(name)) { // TODO determines whether the password and username are correct Cache cache = (); String token = (); ("TOKEN:" + token, name); renderText(token); } else { renderText("Error in username and password"); } }
In addition, there are two things to note:
- Call @Clear before the interface, that is, the login interface should not be intercepted and verified.
- The system's login interface, which should be distinguished from the one in shiro, is two different concepts.
Custom interceptor
package ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; public class MyShiroInterceptor extends AnnotationsAuthorizingMethodInterceptor implements Interceptor { public MyShiroInterceptor() { getMethodInterceptors(); } public void intercept(final Invocation inv) { try { String token = ().getHeader("token"); if ((token)) { BaseController b = (BaseController) (); ("Missing token"); return; } else { Subject s = (); JWTToken jwtToken = new JWTToken(token); (jwtToken); (); } } catch (Throwable e) { if (e instanceof AuthorizationException) { doProcessuUnauthorization(()); } ("Permission Error:", e); try { throw e; } catch (Throwable throwable) { (); } } } /** * Unauthorized processing * * @param controller controller */ private void doProcessuUnauthorization(Controller controller) { ("/login/noLogin"); } }
The above code is very long, let's focus on these lines:
String token = ().getHeader("token"); if ((token)) { BaseController b = (BaseController) (); ("Missing token"); return; } else { Subject s = (); JWTToken jwtToken = new JWTToken(token); (jwtToken); (); }
The logic can be described as: obtaining the token, if it is not empty, convert it into a JWTToken object, and then calling shiro's login interface:(jwtToken)
。
And shiro's login method will trigger the verification interface in custom Realm:
/** * Custom authentication */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { String token = (String) (); // Decrypt and obtain username for comparison with the database String userName = (token); if (userName == null || userName == "") { throw new AuthenticationException("Token verification failed"); } return new SimpleAuthenticationInfo(token, token, getName()); }
Among them, JwtUtils. The specific code of getUsername is as follows, and it corresponds to setting the token:
/** * @return username included in token */ public static String getUsername(String token) { Cache cache = (); String username = (String)(RedisKeyPreFix.NEW_OA_MANAGE_TOKEN_PREFIX + token); return username; }
In this way, shiro embedding is achieved.
Legacy issues
One of the problems that is currently missing is that shiro annotations cannot be implemented for permission verification. We are also planning to implement this problem with ShiroPlugin. Since jfinal has been upgraded to 4.8, and shiroPlugin is still stuck in the version that supports jfinal, so we need to download the jfianl-shiro-plugin source code to make some modifications.
This is the article about the implementation method of embedding shiro verification in stateless mode in jfinal. For more related jfinal shiro verification content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!