我在验证用户凭据时遇到问题。当我第一次提供正确的凭据时,一切正常,但是先提供无效的凭据,然后再提供正确的凭据,我收到无效的凭据错误。我使用Postman Basic 验证。
我的配置类:
@Configuration @EnableWebSecurity public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Autowired private CustomAuthenticationEntryPoint authenticationEntryPoint; @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable().authorizeRequests() .antMatchers(HttpMethod.POST ,"/login").permitAll() .antMatchers("/admin").hasAuthority("ADMIN") .anyRequest().authenticated().and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.ALWAYS).and() .logout() .deleteCookies("remove") .invalidateHttpSession(true); http.rememberMe().disable(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(this.userService) .and().eraseCredentials(true); } @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
还有我的控制器类
@PostMapping public ResponseEntity loginButtonClicked(HttpServletRequest request) { HttpSession session = request.getSession(); final String authorization = request.getHeader("Authorization"); String[] authorizationData=null; if (authorization != null && authorization.startsWith("Basic")) { // Authorization: Basic base64credentials String base64Credentials = authorization.substring("Basic" .length()).trim(); String credentials = new String(Base64.getDecoder().decode(base64Credentials), Charset.forName("UTF-8")); // credentials = username:password authorizationData = credentials.split(":", 2); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(authorizationData[0], authorizationData[1],Arrays.asList(new SimpleGrantedAuthority("USER"))); User user = userService.findUserEntityByLogin(authorizationData[0]); if(user != null && user.getFromWhenAcceptLoginAttempts() != null && (user.getFromWhenAcceptLoginAttempts()).isBefore(LocalDateTime.now())){ // Authenticate the user Authentication authentication = authenticationManager.authenticate(authRequest); SecurityContext securityContext = SecurityContextHolder.getContext(); securityContext.setAuthentication(authentication); // Create a new session and add the security context. session = request.getSession(); session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext); return new ResponseEntity(new LoginResponseObject(200,"ACCESS GRANTED. YOU HAVE BEEN AUTHENTICATED"), HttpStatus.OK); }else{ session.getId(); SecurityContextHolder.clearContext(); if(session != null) { session.invalidate(); } return new ResponseEntity(new ErrorObject(403,"TOO MANY LOGIN REQUESTS","YOU HAVE ENTERED TOO MANY WRONG CREDENTIALS. YOUR ACCOUNT HAS BEEN BLOCKED FOR 15 MINUTES.", "/login"), HttpStatus.FORBIDDEN); } }else{ session.getId(); SecurityContextHolder.clearContext(); if(session != null) { session.invalidate(); } return new ResponseEntity(new ErrorObject(401,"INVALID DATA","YOU HAVE ENTERED WRONG USERNAME/PASSWORD CREDENTIALS", "/login"), HttpStatus.UNAUTHORIZED); } } @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Bean public ObjectMapper objectMapper(){ return new ObjectMapper(); } @Bean public HttpSessionEventPublisher httpSessionEventPublisher() { return new HttpSessionEventPublisher(); }
答案 0 :(得分:0)
尝试在.deleteCookies("JSESSONID")
类中编写SpringSecurityConfig
。
答案 1 :(得分:0)
问题是由于您的sessionCreationPolicy,请求存储在缓存中。
为避免此问题,您可以在http安全配置中添加.requestCache().requestCache(new NullRequestCache())
来覆盖默认的请求缓存配置,但是要小心,因为这可能会产生另一种副作用(取决于您的应用程序)。
如果您不需要会话,则可以选择其他会话策略:
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
。
另一种替代方法是中继Spring的BasicAuthenticationFilter。该过滤器为您执行所有身份验证逻辑。要启用它,只需在http安全配置中添加.httpBasic()
。
您可能要在身份验证成功/失败时添加自定义逻辑。在这种情况下,您只需要创建一个自定义过滤器(CustomBasicAuthenticationFilter
)即可扩展BasicAuthenticationFilter
类并覆盖方法onSuccessfulAuthentication()
和onUnsuccessfulAuthentication()
。您无需添加.httpBasic()
,但需要在正确的位置插入自定义过滤器:
.addFilterAfter(new CustomBasicAuthenticationFilter(authenticationManager), LogoutFilter.class)
。
这3种解决方案中的任何一种都可以避免您的问题。