第一次使用 springSecurity,采用前后端分離的方式,vue 開發 Web 端通過正常方式訪問,App 端需要設計為不強制登錄(只要不是 App 安裝、版本更新、注銷登錄,在第一次登錄后就不需要再次登錄)。由於 security 默認的登錄方式不支持這種方式,需要重寫過濾器,修改為支持從 header 中獲取 token 值,根據 token 設置當前登錄對象。
思路大概為:App 端登錄成功,后端返回 token 值,App 保存在本地后在后面的每次請求中都在 header 中帶着 token 進行請求。后端重寫過濾器,在過濾器中解析 token 值並將 token 中帶的對象放到登錄用戶中,讓 security 認為請求已經是在登錄狀態下進行。
1、新建AuthenticationTokenFilter
繼承OncePerRequestFilter
,重寫doFilterInternal
方法。在doFilterInternal
中獲取 header 中帶着的驗證信息,解析 token 值獲取用戶信息,並將用戶信息設置到SecurityContextHolder
中。
@Component
public class AuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private UserService userService; //用戶信息service
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String authHeader = request.getHeader("token");//獲取header中的驗證信息
if (authHeader != null && authHeader.startsWith("Bearer ")) {
final String authToken = authHeader.substring("Bearer ".length());
String username = JwtUtils.parseToken(authToken, "\_secret"); //從token中獲取用戶信息,jwtUtils自定義的token加解密方式
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userService.loadUserByUsername(username);//根據用戶名獲取用戶對象
if (userDetails != null) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
//設置為已登錄
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
chain.doFilter(request, response);
}
}
2、在繼承了WebSecurityConfigurerAdapter
的類中增加以下內容
@Autowired AuthenticationTokenFilter authenticationTokenFilter; // token 攔截器
@Override protected void configure(HttpSecurity http) throws Exception { // 加上addFilterBefore執行token攔截器 http .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) ...
作者:524021835
鏈接:https://hacpai.com/article/1545318463746
來源:黑客派
協議:CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0/