首页 文章

无效凭据后,Spring引导安全性无法登录

提问于
浏览
0

我在验证用户凭据时遇到问题 . 当我第一次提供正确的凭据时,一切正常,但首先提供无效的凭据,然后给出正确的凭据,我得到无效的凭据错误 . 我使用Postman Basic Auth .

我的配置类:

@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

    问题是由于sessionCreationPolicy,请求存储在缓存中 .

    要避免此问题,您可以在http安全配置中添加 .requestCache().requestCache(new NullRequestCache()) 以覆盖默认请求缓存配置,但要小心,因为这可能会产生另一个副作用(这取决于您的应用程序) .

    如果您不需要会话,可以选择其他会话策略:

    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .

    另一种方法是在Spring的BasicAuthenticationFilter中进行中继 . 此过滤器为您执行所有身份验证逻辑 . 要启用它,您只需在http安全配置中添加 .httpBasic() .

    您可能希望在身份验证成功/失败时添加自定义逻辑 . 在这种情况下,您只需创建一个扩展 BasicAuthenticationFilter 类的自定义过滤器( CustomBasicAuthenticationFilter )并覆盖方法 onSuccessfulAuthentication()onUnsuccessfulAuthentication() . 您无需添加 .httpBasic() ,但需要在正确的位置插入自定义过滤器:

    .addFilterAfter(new CustomBasicAuthenticationFilter(authenticationManager), LogoutFilter.class) .

    任何这三种解决方案都可以避免您的问题 .

  • 0

    尝试在 SpringSecurityConfig 类中编写 .deleteCookies("JSESSONID") .

相关问题