无效的凭据后,Spring Boot安全性无法登录

时间:2018-08-06 12:49:52

标签: java spring security spring-boot login

我在验证用户凭据时遇到问题。当我第一次提供正确的凭据时,一切正常,但是先提供无效的凭据,然后再提供正确的凭据,我收到无效的凭据错误。我使用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();
            } 

2 个答案:

答案 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种解决方案中的任何一种都可以避免您的问题。