admin管理员组

文章数量:1399490

I have a problem with my SpringBoot app where I cannot obtain userDetails from web authentication.

I created custom AuthenticationProvider which executes login using external service.

public class CustomAuthenticationProvider implements AuthenticationProvider {

        private final WebAppXSession webAppXSession;

        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                log.info("Authenticating user: {}", authentication);
                final String username = authentication.getName();
                final String password = authentication.getCredentials().toString();

                try {
                        User user = webAppXSession.login(username, password);
                        UsernamePasswordAuthenticationToken token =  new UsernamePasswordAuthenticationToken(user.getUid(), null, List.of( new SimpleGrantedAuthority("ROLE_USER")));
                        token.setDetails(user);
                        return token;
                } catch (InvalidCredentialsException e) {
                        throw new BadCredentialsException("Invalid username or password", e);
                } catch (Exception e) {
                        throw new AuthenticationServiceException("Authentication failed: " + e.getMessage(), e);
                }
        }

}

I added this provider to my AuthenticationManager bean and it works just fine. The problem occurs when I try to fetch authentication from SecurityContextHolder.getContext() in my session validation endpoint, because Authentication object always contains anonymousUser.

I tried using static securityContextHolder in my controller but it gave no effect.

Here is my login endpoint

@PostMapping("/login")
        public ResponseEntity<?> login(@RequestBody UserCredentials credentials) {
                try {
                        UsernamePasswordAuthenticationToken authToken =
                                new UsernamePasswordAuthenticationToken(
                                        credentials.getUsername(),
                                        credentials.getPassword()
                                );

                        Authentication authentication = authenticationManager.authenticate(authToken);
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                        return ResponseEntity.ok(response);
                } catch (Exception e) {
                        return ResponseEntity
                                .status(HttpStatus.UNAUTHORIZED)
                                .body(Map.of("error", "Authentication failed", "message", e.getMessage()));
                }
        }

And session check

@GetMapping("/session")
        public ResponseEntity<?> checkSession() {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

            
                if (authentication != null && authentication.isAuthenticated()){
                        Map<String, Object> response = new HashMap<>();
                        response.put("principal", authentication.getPrincipal());
                        response.put("authenticated", true);
                        return ResponseEntity.ok(response);
                }

                return ResponseEntity
                        .status(HttpStatus.UNAUTHORIZED)
                        .body(Map.of("authenticated", false));
        }

What's weird is that when I check the session it indicates that it's valid but as a anonymousUser.

Here is output of authentication object from login method

Authentication: UsernamePasswordAuthenticationToken [Principal=AsAAAAALJjE3dC, Credentials=[PROTECTED], Authenticated=true, Details=AsAAAAALJjE3dC, Granted Authorities=[ROLE_USER]]

And here is output of authentication from session check

Authentication: AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=cd74f829-05cb-4ec7-85bf-1e225c97b1a1], Granted Authorities=[ROLE_ANONYMOUS]]

I also tried using diffrent browsers, postman and curl but each gave the same output

For context I am using JdbcHttpSession with Postgresql, Java 21, Spring 3.4.4 and here is also my filterChain

@Bean
        public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                return http
                        .cors(cors -> cors.configurationSource(corsConfigurationSource()))
                        .requestCache(RequestCacheConfigurer::disable)
                        .csrf(csrf -> csrf
                                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                                .ignoringRequestMatchers("/api/auth/login", "/api/auth/logout")
                        )
                        .authorizeHttpRequests(request -> request
                                .requestMatchers("/api/auth/login", "/api/auth/session", "/api/auth/logout", "/api/auth/test-auth").permitAll()
                                .anyRequest().authenticated()
                        )
                        .sessionManagement(session -> session
                                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                        )
                        .securityContext(securityContext -> securityContext
                                .securityContextRepository(securityContextRepository())
                        )
                        .exceptionHandling(exceptions -> exceptions
                                .authenticationEntryPoint((request, response, authException) -> {
                                        response.setStatus(401);
                                        response.getWriter().write("Unauthorized: " + authException.getMessage());
                                })
                        )
                        .logout(logout -> logout
                                .logoutRequestMatcher(new AntPathRequestMatcher("/api/auth/logout", "POST"))
                                .logoutSuccessHandler((request, response, authentication) -> {
                                        response.setStatus(200);
                                        response.getWriter().write("{\"message\":\"Logged out successfully\"}");
                                })
                                .invalidateHttpSession(true)
                                .clearAuthentication(true)
                        )
                        .build();
        }

I cannot find the issue in my code so I hope that someone here can help me with it.

本文标签: javaSecurityContextHolder getAuthentication always return AnonymousUserStack Overflow