1)登录时通过filter创建jwt token
2)访问页面时通过filter验证token,如果验证通过,继续访问,否则返回错误信息。
所以最重要的是两个Filter,我们命名为:
JwtAuthenFilter (登录Filter)
JwtAuthorFilter (认证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之前,所以不需要再处理其他。
@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前,
不需要特殊处理。
用界面登录,用户名默认:admin,密码默认:1
登录成功后,返回token,把token拷贝下来待用
这里是“BearereyJhbGciOiJIUzUxMiJ9.SnNDWEY0a20yUm1FcFB6MERTQyt1dTByUG44TWh5ZU1kbVhMSW94dGoybmQ3Y0Iwc2U2L0ozM2tqZlo0LytKY1poVDNuelZQMHJJUVRvSnh0RU5peVM5YXJtQ2RoQ0JKbGY1N0UvOE5semM9.0vlPr3ZRhvbzhg9avo7MgdANXZew-DTP0v8NgR9NBsiIdPovo7YmEVoNsP1vs4TK_wVLZ3FSLh9mghPi5LwNWQ”
打开postman
Header中设置Authorization,如上图。
点击Send,成功后,会显示“token”字符串。
如果无效token,会显示"no Authorization, so quit now.",如下:
最后最好下载本文的源代码一边看文档一边调试。