【问题标题】:Spring-boot authentication春季启动认证
【发布时间】:2025-12-11 06:30:01
【问题描述】:

我有很少的 Spring-boot 控制器类来公开很少的其余 Web 服务。每当某些用户尝试访问这些服务中的任何一个时,我都需要调用 Web 服务来检查用户(用户 ID 将作为 RequestHeader 传递)是否被授权。如果未经授权,需要向用户显示错误页面(freemarker 模板)。

我不想编写一个方法来调用身份验证 Web 服务并从每个控制器方法调用它并抛出异常并使用 @ControllerAdvice 将用户重定向到拒绝访问错误页面,因为这里我必须调用该方法来自所有控制器方法。

我不确定是否可以使用 WebSecurityConfigurerAdapter/AuthenticationManagerBuilder 来调用 Web 服务并进行验证。

我正在寻找一些解决方案,我将编写一个拦截器,spring-boot 将在调用控制器类之前调用​​ web 服务,并且如果验证失败,将能够重定向到错误页面。

【问题讨论】:

标签: spring spring-mvc spring-boot spring-security spring-web


【解决方案1】:

作为建议,请花几分钟阅读有关 Spring Security (https://projects.spring.io/spring-security/) 的信息,您必须对其进行配置,并且您可能会花费比预期更多的时间,无论如何您比自己做安全获得的利润要多得多。

好处是这样的:

@PreAuthorize("hasRole('ROLE_USER')")

在每个地方,您都可以让用户通过 SecurityContext 登录,例如:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();

SpringSecurity 使用 JWT (JsonWebToken) 对用户进行身份验证的方式非常好,因为您可以传递和检索所需的所有信息:

public class CustomTokenEnhancer implements TokenEnhancer {

@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
    User user = (User) authentication.getPrincipal();
    final Map<String, Object> additionalInfo = new HashMap<>();

    additionalInfo.put("customInfo", "some_stuff_here");
    additionalInfo.put("authorities", user.getAuthorities());

    ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);

    return accessToken;
}

}

您可以忘记所有可能的问题(身份验证错误、网络钓鱼、xss 或 csrf..),因为它适用于公钥/私钥和机密,因此任何人都可以创建令牌。

【讨论】: