@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private JwtFilter jwtFilter;
@Resource
AuthenticationEntryPoint authenticationEntryPoint;
@Resource
AccessDeniedHandler accessDeniedHandler;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//关闭csrf
.csrf().disable()
//不通过Session获取SecurityContext
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
// 对于登录接口 允许匿名访问
//.antMatchers("/login").anonymous()
//.antMatchers("/login","/doc.html","/webjars
public static void renderString(HttpServletResponse response, String string) {
try
{
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void setDownLoadHeader(String filename, ServletContext context, HttpServletResponse response) throws UnsupportedEncodingException {
String mimeType = context.getMimeType(filename);//获取文件的mime类型
response.setHeader("content-type",mimeType);
String fname= URLEncoder.encode(filename,"UTF-8");
response.setHeader("Content-disposition","attachment; filename="+fname);
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
// response.setCharacterEncoding("utf-8");
}
}
6)AccessDeniedHandlerImpl
@Component
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
//打印下异常
accessDeniedException.printStackTrace();
ResponseResult result = ResponseResult.fail(ResponseCode.UNAUTHORI.code,ResponseCode.UNAUTHORI.msg);
//以json的形式相应给前端
WebUtils.renderString(response, JSONUtil.toJsonStr(result));
}
}
7)AuthenticationEntryPointImpl
@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
//打印下异常
authException.printStackTrace();
//登录认证是根据不同的情况,提示不同的错误
ResponseResult result = null;
//BadCredentialsException密码错误的异常,坏的凭据
//InsufficientAuthenticationException,凭据不足
if(authException instanceof BadCredentialsException){
result = ResponseResult.fail(ResponseCode.FAIL.code,authException.getMessage());
}else if(authException instanceof InsufficientAuthenticationException){
result = ResponseResult.fail(ResponseCode.UNLOGIN.code,authException.getMessage());
}else{
result = ResponseResult.fail(ResponseCode.FAIL.code,"认证和授权出线问题");
}
//以json的形式相应给前端
WebUtils.renderString(response, JSONUtil.toJsonStr(result));
}
}
3、注意事项
在使用UsernamePasswordAuthenticationToken进行用户和密码认证时,需要调用AuthenticationManager认证管理器进行管理,在这个过程中一定不能忘记实现UserDetailsServiceImpl和UserDetailImpl类,不然会走默认的认证流程,这时候就查询不到用户数据,会报出Handler dispatch failed; nested exception is java.lang.StackOverflowError这个异常
4、自定义登录@Service//这里是user的业务层,用的mybatisplus public class UserServiceImpl extends ServiceImplimplements IUserService { @Autowired private AuthenticationManager authenticationManager; @Override public ResponseResult login(UserDto userDto) { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDto.getUserName(),userDto.getUserPass()); Authentication authenticate = authenticationManager.authenticate(authenticationToken); if(Objects.isNull(authenticate)){ // throw new BadCredentialsException("用户名或密码错误"); return ResponseResult.fail(ResponseCode.FAIL.code,"账号或密码错误"); } UserDetailImpl userDetail = (UserDetailImpl)authenticate.getPrincipal(); String userId = userDetail.getUser().getUserId().toString(); String jwt = JwtUtil.createJWT(userId); return ResponseResult.success(MapUtil.builder().put("token",jwt).build()); } }



