SpringSecurity中jwt認證核心原理如下:
1)登錄時通過filter創建jwt token
2)訪問頁面時通過filter驗證token,如果驗證通過,繼續訪問,否則返回錯誤信息。
所以最重要的是兩個Filter,我們命名爲:
JwtAuthenFilter (登錄Filter)
JwtAuthorFilter (認證Filter)
1、創建JwtAuthenFilter登錄Filter
首先Filter繼承於UsernamePasswordAuthenticationFilter,這樣就可以用這個Filter本身的機制。
public class JwtAuthenFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JwtAuthenFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login.html", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
try {
LoginUser loginUser = new LoginUser();
loginUser.setUsername(request.getParameter("username"));
loginUser.setPassword(request.getParameter("password"));
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword(), new ArrayList<>())
);
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
}
// 成功驗證後調用的方法
// 如果驗證成功,就生成token並返回
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain,
Authentication authResult) throws IOException, ServletException {
//jwtToken生成
}
}
接着需要註冊到http配置上,config中配置如下:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/login.html", "/use/**").permitAll()
.anyRequest().authenticated() //任何未匹配的URL都要進行身份驗證
.and()
.formLogin()
.loginPage("/login.html")
.and()
.logout()
.logoutUrl("/logout") //註銷URL
.logoutSuccessUrl("/login.html")
.and()
.addFilter(new JwtAuthenFilter(authenticationManager()));
}
其中最後一句
.addFilter(new JwtAuthenFilter(authenticationManager()));
將該Filter加入了。
注意:根據源代碼跟蹤,好像默認它就在UsernamePasswordAuthenticationFilter之前,所以不需要再處理其他。
2、創建JwtAuthorFilter認證Filter
@Component
public class JwtAuthorFilter extends OncePerRequestFilter {
@Value("${jwt.isFilter}")
private String isFilter;
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException{
//解析Jwt,並進行認證
}
}
該Filter繼承於OncePerRequestFilter,其位置是在springSecurityFilterChain之前,所以調用會在所有的springsecurity前,
不需要特殊處理。
3、結合兩個Filter聯合調試
用界面登錄,用戶名默認:admin,密碼默認:1
登錄成功後,返回token,把token拷貝下來待用
這裏是“BearereyJhbGciOiJIUzUxMiJ9.SnNDWEY0a20yUm1FcFB6MERTQyt1dTByUG44TWh5ZU1kbVhMSW94dGoybmQ3Y0Iwc2U2L0ozM2tqZlo0LytKY1poVDNuelZQMHJJUVRvSnh0RU5peVM5YXJtQ2RoQ0JKbGY1N0UvOE5semM9.0vlPr3ZRhvbzhg9avo7MgdANXZew-DTP0v8NgR9NBsiIdPovo7YmEVoNsP1vs4TK_wVLZ3FSLh9mghPi5LwNWQ”
打開postman
Header中設置Authorization,如上圖。
點擊Send,成功後,會顯示“token”字符串。
如果無效token,會顯示"no Authorization, so quit now.",如下:
最後最好下載本文的源代碼一邊看文檔一邊調試。