本编主要是实现如果结合JWT实现登录和访问时的验证
目录
1.2 AjaxAuthenticationSuccessHandler
2.1、自定义 JwtAuthenticationTokenFilter
1、实现登录
1.1 AjaxResponseBody
加入jwtToken属性
public class AjaxResponseBody implements Serializable{
private String status;
private String msg;
private Object result;
//加入jwt属性
private String jwtToken;
1.2 AjaxAuthenticationSuccessHandler
登录认证成功之后,在客户端的发会信息中加入jwt token
@Component
public class AjaxAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
AjaxResponseBody responseBody = new AjaxResponseBody();
responseBody.setStatus("200");
responseBody.setMsg("Login Success! 登录成功");
//登录成功加入jwt token
//SelfUserDetails是在UserDetailsService中产生的,这一点有点类似shiro的用户对象
SelfUserDetails userDetails = (SelfUserDetails) authentication.getPrincipal();
String jwtToken = JwtTokenUtil.generateToken(userDetails.getUsername(), 300, "_secret");
responseBody.setJwtToken(jwtToken);
httpServletResponse.getWriter().write(JSON.toJSONString(responseBody));
}
}
2、访问拦截认证
2.1、自定义 JwtAuthenticationTokenFilter
package com.grsoft.security.filter;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Description: 登录前做token的校验
* @author: : Steven
* @Date: 2020/2/14 17:41
*/
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
//注意1.普通的doFilter,实现存储“已过滤”的请求属性,如果属性已经存在,则继续进行而不再过滤。
// 2.doFilterInternal和doFilter相同功能,但保证在单个请求线程中每个请求只调用一次。
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
// 获得请求的URL
String url = request.getRequestURL().toString();
if (url.endsWith("/login")) {
chain.doFilter(request, response);
} else {
//此处省略JWT校验代码
if (Jwt校验通过) {
chain.doFilter(request, response);
} else {
response.sendRedirect("/login");
}
}
}
}
2.2 WebSecurityConfigurerAdapter
在WebSecurityConfigurerAdapter中加入自定义的JwtAuthenticationTokenFilter
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.httpBasic().authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.anyRequest()
.authenticated()// 其他 url 需要身份认证
.and()
.formLogin() //开启登录
// .loginPage("/myLogin.html")// 自定义登录页面
// .loginProcessingUrl("/login.do")// 自定义登录controller
.successHandler(authenticationSuccessHandler) // 登录成功
.failureHandler(authenticationFailureHandler) // 登录失败
.permitAll()
.and()
.logout()
.logoutSuccessHandler(logoutSuccessHandler)
.permitAll();
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 无权访问 JSON 格式的数据
//加入过滤器
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}