如何在 Spring Security 6 中访问经过身份验证的用户详细信息?

问题描述 投票:0回答:1

我正在使用 Spring Security 6.2.1 和 Spring MVC 6.1.0

我想访问当前登录用户的用户名,如何从 SecurityContextHolder 访问用户详细信息? 从 spring security 5 更新到 6 起,当尝试通过从 SecurityContextHolder 获取身份验证来验证用户身份时,将返回 null。以前在使用 Spring Security/MVC 5 时,这没有任何问题。

public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    
    String name = authentication.getName();
    String password = authentication.getCredentials().toString();

    User user = authenticationDAO.getUser(name);

    if (user != null && encoder.matches(password, user.getPassword())) {
        List<String> roles = authenticationDAO.getRoles(user.getId());

        List<GrantedAuthority> authorities = new ArrayList<>();

        if (roles != null) {
            for (String role : roles) {
                authorities.add(new SimpleGrantedAuthority(role));
            }
        }

        return new UsernamePasswordAuthenticationToken(name, password, authorities);
    }

    return null;
}

此时,当我稍后尝试访问应存储的用户名时,身份验证对象为空。

public String getAuthenticatedUser() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication == null || AnonymousAuthenticationToken.class.isAssignableFrom(authentication.getClass())) {
        return null;
    }

    return authentication.getName();
}
spring authentication spring-mvc spring-security
1个回答
0
投票

假设您有自定义

UsernamePasswordAuthenticationFilter
,您必须明确提供并设置
SecurityContextRepository
。欲了解更多详细信息,请参见此处: 会话管理迁移

现在,如果这是您的情况,请声明一个专用 bean:

@Bean
public SecurityContextRepository delegatingSecurityContextRepository() {
    return new DelegatingSecurityContextRepository(
            new RequestAttributeSecurityContextRepository(),
            new HttpSessionSecurityContextRepository());
}

然后将其注入到您的 UsernamePasswordAuthenticationFilter 中进行如下设置:

@Component
public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final SecurityContextRepository securityContextRepository;
    private final AuthenticationFailureHandler authenticationFailureHandler;
    private final AuthenticationSuccessHandler authenticationSuccessHandler;

    @PostConstruct
    private void setup() {

        /* Settings must match those in the login-form */
        super.setUsernameParameter("identifier");
        super.setPasswordParameter("password");
        super.setFilterProcessesUrl(AUTH_FORM_AUTHENTICATION_URL);

        super.setSecurityContextRepository(securityContextRepository);
        super.setAuthenticationFailureHandler(authenticationFailureHandler);
        super.setAuthenticationSuccessHandler(authenticationSuccessHandler);

        super.afterPropertiesSet();
    }

    public CustomUsernamePasswordAuthenticationFilter(
            @Qualifier("customProviderManager") AuthenticationManager customProviderManager,
            @Qualifier("delegatingSecurityContextRepository") SecurityContextRepository securityContextRepository,
            @Qualifier("customAuthenticationFailureHandler") AuthenticationFailureHandler authenticationFailureHandler,
            @Qualifier("customAuthenticationSuccessHandler") AuthenticationSuccessHandler authenticationSuccessHandler) {

        this.securityContextRepository = securityContextRepository;
        this.authenticationFailureHandler = authenticationFailureHandler;
        this.authenticationSuccessHandler = authenticationSuccessHandler;

        super.setAuthenticationManager(customProviderManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!request.getMethod().equals("POST"))
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());

        String identifier = super.obtainUsername(request);
        identifier = identifier != null ? identifier.trim() : "";
        String password = super.obtainPassword(request);
        password = password != null ? password : "";

        CustomUsernamePasswordAuthenticationToken authRequest = CustomUsernamePasswordAuthenticationToken.unauthenticated(identifier, password);

        super.setDetails(request, authRequest);
        return super.getAuthenticationManager().authenticate(authRequest);
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.