In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/03 Report--
JWTUtil
We use the tool class of JWT to generate our token, which mainly has two methods: generating token and verifying token
When generating token, specify the token expiration time EXPIRE_TIME and signature key SECRET, then write date and username to token and sign using the HS256 signature algorithm with the key
Date date = new Date (System.currentTimeMillis () + EXPIRE_TIME); Algorithm algorithm = Algorithm.HMAC256 (SECRET); JWT.create () .withClaim ("username", username) / / Expiration time .withExpiresAt (date) / / create a new JWT and mark it with the given algorithm .sign (algorithm); database table
Role: role; permission: permission; ban: blocked status
Each user has a corresponding role (user,admin) and permission (normal,vip), while the default permission for the user role is normal, and the default permission for the admin role is vip (of course, user can also be vip)
Filter
In the previous article, we used shiro's default permission to intercept Filter, but because of the integration of JWT, we need to customize our own filter JWTFilter,JWTFilter inherits BasicHttpAuthenticationFilter, and some of the original methods are overridden
The filter has three main steps:
Verify whether the request header has token ((HttpServletRequest) request) .getHeader ("Token")! = null
If there is token, execute the login () method of shiro, and submit the token to Realm for verification; if there is no token, the current status is tourist status (or other APIs that do not require authentication)
@ Overrideprotected boolean isAccessAllowed (ServletRequest request, ServletResponse response, Object mappedValue) throws UnauthorizedException {/ / determine whether the request header of the request is marked with "Token" if (HttpServletRequest) request) .getHeader ("Token")! = null) {/ / if it exists, log in to the executeLogin method and check whether token is correct try {executeLogin (request, response); return true } catch (Exception e) {/ / token error responseError (response, e.getMessage ();}} / / if the request header does not exist Token, it may be a login operation or a visitor status visit. Without checking token, directly return true return true;} @ Overrideprotected boolean executeLogin (ServletRequest request, ServletResponse response) throws Exception {HttpServletRequest httpServletRequest = (HttpServletRequest) request String token = httpServletRequest.getHeader ("Token"); JWTToken jwtToken = new JWTToken (token); / / submitted to realm for login. If there is an error, he will throw an exception and be caught getSubject (request, response) .login (jwtToken); / / if no exception is thrown, login is successful and true return true is returned } if an error occurs during token verification, such as token verification failure, then I will treat the request as an authentication failure and redirect to / unauthorized/**
In addition, I put cross-domain support into this filter to handle
Realm class
It is still our custom Realm. For those who don't know this yet, you can take a look at my last shiro article first.
Identity authentication
If (username = = null | |! JWTUtil.verify (token, username)) {throw new AuthenticationException ("token authentication failed!") ;} String password = userMapper.getPassword (username); if (password = = null) {throw new AuthenticationException ("this user does not exist!") ;} int ban = userMapper.checkUserBanStatus (username); if (ban = = 1) {throw new AuthenticationException ("this user has been blocked!") ;}
Get the incoming token and check whether the token is valid, whether the user exists, and whether the user's name is sealed.
Authorization SimpleAuthorizationInfo info = new SimpleAuthorizationInfo (); / / obtain the user role String role = userMapper.getRole (username); / / each role has the default permission String rolePermission = userMapper.getRolePermission (username); / / each user can set new permissions String permission = userMapper.getPermission (username); Set roleSet = new HashSet (); Set permissionSet = new HashSet (); / / need to encapsulate role and permission into Set as parameters roleSet.add (role) of info.setRoles () and info.setStringPermissions () PermissionSet.add (rolePermission); permissionSet.add (permission); / / set the roles and permissions that the user has info.setRoles (roleSet); info.setStringPermissions (permissionSet)
Use the username obtained in token to find out the roles and permissions owned by the user from the database and store them in SimpleAuthorizationInfo.
ShiroConfig configuration class
Set up our custom filter and pass all requests through our filter, except for the / unauthorized/** that we use to handle unauthenticated requests
@ Beanpublic ShiroFilterFactoryBean factory (SecurityManager securityManager) {ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean (); / / add your own filter and name it jwt Map filterMap = new HashMap (); / / set our custom JWT filter filterMap.put ("jwt", new JWTFilter (); factoryBean.setFilters (filterMap); factoryBean.setSecurityManager (securityManager); Map filterRuleMap = new HashMap ()) / / all requests are made through our own JWTFilter filterRuleMap.put ("/ * *", "jwt"); / / access / unauthorized/** does not go through JWTFilter filterRuleMap.put ("/ unauthorized/**", "anon"); factoryBean.setFilterChainDefinitionMap (filterRuleMap); return factoryBean;} permission control annotations @ RequiresRoles, @ RequiresPermissions
These two annotations are our main access control annotations, such as
/ / have admin roles to access @ RequiresRoles ("admin") / / have user or admin roles to access @ RequiresRoles (logical = Logical.OR, value = {"user", "admin"}) / / have vip and normal permissions to access @ RequiresPermissions (logical = Logical.AND, value = {"vip", "normal"}) / / have user or admin roles And with vip permission, you can visit @ GetMapping ("/ getVipMessage") @ RequiresRoles (logical = Logical.OR, value = {"user", "admin"}) @ RequiresPermissions ("vip") public ResultMap getVipMessage () {return resultMap.success (). Code (200). Message ("successfully get vip information!") ;}
When the API we write has the above comments, if the request does not have token or token but the permission authentication fails, a UnauthenticatedException exception will be reported, but I have handled these exceptions centrally in the ExceptionController class.
@ ExceptionHandler (ShiroException.class) public ResultMap handle401 () {return resultMap.fail () .code (401) .message ("you do not have permission to access!") ;}
In this case, a shiro-related exception will be returned
{"result": "fail", "code": 401, "message": "you do not have permission to access!" }
In addition to the above two, there are @ RequiresAuthentication, @ RequiresUser and other notes
Function realization
User roles are divided into three categories: administrator admin, ordinary user user. The default permission for visitor guest;admin is vip,user. The default permission is normal. When user is upgraded to vip permission, you can access the page with vip permission.
The specific implementation can be found in the source code (address has been given at the beginning)
Landing
The login interface does not have token. When the login password and user name are verified correctly, return token.
@ PostMapping ("/ login") public ResultMap login (@ RequestParam ("username") String username, @ RequestParam ("password") String password) {String realPassword = userMapper.getPassword (username); if (realPassword = = null) {return resultMap.fail () .code (401) .message ("user name error") } else if (! realPassword.equals (password)) {return resultMap.fail (). Code (401). Message ("password error");} else {return resultMap.success (). Code (200) .message (JWTUtil.createToken (username)) } {"result": "success", "code": 200,200, "message": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MjUxODQyMzUsInVzZXJuYW1lIjoiaG93aWUifQ.fG5Qs739Hxy_JjTdSIx_iiwaBD43aKFQMchx9fjaCRo"} exception handling / / catching shiro exception @ ExceptionHandler (ShiroException.class) public ResultMap handle401 () {return resultMap.fail () .code (401) .message ("you do not have permission to access!") ;} / / catch all other exceptions @ ExceptionHandler (Exception.class) public ResultMap globalException (HttpServletRequest request, Throwable ex) {return resultMap.fail () .code (getStatus (request). Value ()) .message ("access error, unable to access:" + ex.getMessage ());} permission control
UserController (accessible by user or admin)
Put @ RequiresRoles on the interface (logical = Logical.OR, value = {"user", "admin"})
Vip permission
Plus @ RequiresPermissions ("vip")
AdminController (accessible by admin)
Put @ RequiresRoles ("admin") on the interface
GuestController (accessible to all)
Do not do permissions to deal with test results
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.