In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces how SpringBoot creates media classes and filters for storing tokens. It is very detailed and has a certain reference value. Friends who are interested must read it!
First, create the ThreadLocalToken class
The purpose of creating the ThreadLocalToken class is:
Create the ThreadLocalToken class in com.example.emos.wx.config.shiro.
Write the following code:
Package com.example.emos.wx.config.shiro;import org.springframework.stereotype.Component;@Componentpublic class ThreadLocalToken {private ThreadLocal local=new ThreadLocal (); / / setToken is required because you want to save the token in ThreadLocal. Public void setToken (String token) {local.set (token);} public String getToken () {return (String) local.get ();} public void clear () {local.remove (); / / delete the bound data}}
The following figure shows the hierarchical relationship of creating a directory:
Second, create the OAuth3Filter class
The purpose of creating the filter:
Because the OAuth3Filter class reads and writes data in ThreadLocal, the OAuth3Filter class must be set to multiple instances, otherwise ThreadLocal will not be available.
In the configuration file, add the key, expiration time and cache expiration time required by JWT.
Emos: jwt: # key secret: abc123456 # token expiration time (days) expire: 5 # token cache time (days) cache-expire: 10
Create the OAuth3Filter class in com.example.emos.wx.config.shiro.
Package com.example.emos.wx.config.shiro;import com.auth0.jwt.exceptions.JWTDecodeException;import com.auth0.jwt.exceptions.TokenExpiredException;import org.apache.commons.lang3.StringUtils;import org.apache.http.HttpStatus;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.web.filter.authc.AuthenticatingFilter;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Scope Import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.web.bind.annotation.RequestMethod;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.concurrent.TimeUnit
After writing @ Scope ("prototype"), it shows that there are multiple instances of Spring using the OAuth3Filter class by default.
@ Value ("${emos.jwt.cache-expire}")
One of the knowledge points investigated is to obtain the property values of the property file from the xml file.
Declare private RedisTemplate redisTemplate because you want to operate in Redis
Once this object is declared, you can read and write to the data in redis.
The filter class is used to distinguish which requests should be processed by shiro and which should not be processed by shiro.
If the request is processed by shiro, then the createToken method is executed
CreateToken takes the token string from the request, then encapsulates it into a token object, OAuth3Token, and hands it over to the shiro framework for processing.
GetRequestToken is a custom method that gets the token string and passes it to the string Token object.
@ Component@Scope ("prototype") public class OAuth3Filter extends AuthenticatingFilter {@ Autowired private ThreadLocalToken threadLocalToken; @ Value ("${emos.jwt.cache-expire}") private int cacheExpire; @ Autowired private JwtUtil jwtUtil; @ Autowired private RedisTemplate redisTemplate After intercepting the request, it is used to encapsulate the token string into a token object * / @ Override protected AuthenticationToken createToken (ServletRequest request, ServletResponse response) throws Exception {/ / get request token String token = getRequestToken ((HttpServletRequest) request); if (StringUtils.isBlank (token)) {return null } return new OAuth3Token (token);}
Let's talk about filter filtering in more detail:
IsAccessAllowed determines which requests can be processed by shiro and which cannot be processed by shiro.
Because request in the isAccessAllowed method is ServletRequest, you need to convert HttpServletRequest
Then determine whether the request request is an options request. If not, it needs to be handled by shiro.
/ * intercept the request to determine whether it needs to be processed by Shiro * / @ Override protected boolean isAccessAllowed (ServletRequest request, ServletResponse response, Object mappedValue) {HttpServletRequest req = (HttpServletRequest) request / / when Ajax submits application/json data, the Options request will be issued first / / the Options request will be released here. There is no need for Shiro to process if (req.getMethod (). Equals (RequestMethod.OPTIONS.name () {return true;} / / except for Options requests, all requests must be processed by Shiro return false }
So, how does shiro handle it?
OnAccessDenied method
Sets the character set of the response and the request header of the response. The setHeader method is used to set cross-domain requests.
/ * this method is used to process all requests that should be processed by Shiro * / @ Override protected boolean onAccessDenied (ServletRequest request, ServletResponse response) throws Exception {HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; resp.setHeader ("Content-Type", "text/html;charset=UTF-8") / / allow cross-domain requests for resp.setHeader ("Access-Control-Allow-Credentials", "true"); resp.setHeader ("Access-Control-Allow-Origin", req.getHeader ("Origin")); / / clear method is used to clean up methods in the threadLocal class, threadLocalToken.clear () / / get the request token. If token does not exist, directly return 401 String token = getRequestToken ((HttpServletRequest) request); if (StringUtils.isBlank (token)) {resp.setStatus (HttpStatus.SC_UNAUTHORIZED); resp.getWriter () .print ("invalid token"); return false;}
Then verify that the token expires.
If there is a problem with validation, an exception is thrown.
By catching exceptions, you can tell if there is something wrong with the token or whether the token has expired.
JWTDecodeException is a content exception.
Query for the existence of tokens in Redis through redisTemplate's hasKey.
If a token exists, delete the old token, regenerate a token, and give it to the client.
The executeLogin method, which lets shiro execute the realm class.
Try {jwtUtil.verifierToken (token); / / check whether the token expires} catch (TokenExpiredException e) {/ / client token expires, query whether there is a token in Redis, and if there is a token, regenerate a token to the client if (redisTemplate.hasKey (token)) {redisTemplate.delete (token) / delete old tokens int userId = jwtUtil.getUserId (token); token = jwtUtil.createToken (userId); / / generate new tokens / / save new tokens to Redis redisTemplate.opsForValue () .set (token, userId + ", cacheExpire, TimeUnit.DAYS) / bind the new token to the thread threadLocalToken.setToken (token);} else {/ / if the token does not exist in Redis, let the user log in to resp.setStatus (HttpStatus.SC_UNAUTHORIZED); resp.getWriter (). Print ("token has expired"); return false }} catch (JWTDecodeException e) {resp.setStatus (HttpStatus.SC_UNAUTHORIZED); resp.getWriter () .print ("invalid token"); return false;} boolean bool = executeLogin (request, response); return bool;}
The information output after a login failure.
@ Override protected boolean onLoginFailure (AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; resp.setStatus (HttpStatus.SC_UNAUTHORIZED); resp.setContentType ("application/json;charset=utf-8"); resp.setHeader ("Access-Control-Allow-Credentials", "true") Resp.setHeader ("Access-Control-Allow-Origin", req.getHeader ("Origin")); try {resp.getWriter () .print (e.getMessage ()); / / capture the message of authentication failure} catch (IOException exception) {} return false;}
Get the token in the request header
/ * get token * / private String getRequestToken (HttpServletRequest httpRequest) in the request header {/ / get token String token = httpRequest.getHeader ("token") from header; / / if token does not exist in header, get token if (StringUtils.isBlank (token)) {token = httpRequest.getParameter ("token");} return token;} from the parameter
The doFilterInternal method inherits from the parent class doFilterInternal and is responsible for intercepting requests and responses. There is no rewriting here.
@ Override public void doFilterInternal (ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {super.doFilterInternal (request, response, chain);}} this is all the content of the article "how SpringBoot creates media classes and filters for storing tokens". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!
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.