【发布时间】:2019-10-20 13:38:42
【问题描述】:
我正在开发一个 Spring Boot 应用程序,使用 Spring Security 来检查用户登录是否成功或用户是否被授权访问里面的资源。
现在无论我输入错误的用户名/密码还是用户被锁定,它总是返回 401 Unauthorized。我想自定义它,如果凭据错误,它将返回 400,如果用户被锁定,它将返回 401。
我已经为应用程序定义了自定义过滤器和身份验证入口点。
public class JWTUsernameAndPasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
....
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
Optional<UserEntity> userEntity = userService
.findByUserId(request.getParameter("username"));
if (userEntity.isPresent()) {
if (userEntity.get().getStatus().equals("LOCKED")) {
throw new BadCredentialsException("User is locked!"); //I want it to return status 403 here
}
}
String privateKey = userService.findByUserId(request.getParameter("username")).get().getLoginKey();
String username = request.getParameter("username");
String password = CryptoUtil.decrypt(privateKey, request.getParameter("password"));
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
password, Collections.emptyList());
return authenticationManager.authenticate(authenticationToken);
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
String username = request.getParameter("username");
try {
// Do some process stuff....
} catch (Exception ex) {
log.error(ex);
}
super.unsuccessfulAuthentication(request, response, failed); // I want to return 400 here
}
}
public class JwtAuthenticationExceptionEntryPoint implements AuthenticationEntryPoint {
@Getter
@Value("${application.version}")
private String version;
@Getter
@Value("${application.name}")
private String applicationName;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
RESTFulStatus status = new RESTFulStatus(RESTFulStatus.STATUS_ERROR, HttpStatus.UNAUTHORIZED.value(),
HttpStatus.UNAUTHORIZED.getReasonPhrase(),
authException.getMessage(), version, applicationName, Instant.now(), request.getRequestURI());
log.error(authException.getMessage());
ObjectMapper mapper = new ObjectMapper();
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(mapper.writeValueAsString(status));
}
}
配置类
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationExceptionEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().cacheControl();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.csrf().disable();
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and()
.addFilter(new JWTUsernameAndPasswordAuthenticationFilter(authenticationManager(), jwtConfig, userService, accessHistoryService))
.addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtConfig)).authorizeRequests();
http.authorizeRequests().antMatchers(HttpMethod.POST, jwtConfig.getUri()).permitAll()
.antMatchers("/auth/**").permitAll()
.antMatchers("/1/**").hasRole(RoleConstant.ROLE_ADMIN)
.antMatchers("/test/**").hasAnyRole(RoleConstant.ROLE_ADMIN)
.antMatchers("/report/**").hasAnyRole(RoleConstant.ROLE_ADMIN, RoleConstant.ROLE_REPORT)
.anyRequest().authenticated();
// If a user try to access a resource without having enough permissions
http.exceptionHandling().accessDeniedPage("/login");
//test in browser
http.httpBasic();
}
}
【问题讨论】:
标签: spring-boot spring-security