Spring security 在SpringOAuth2(sso应用程序)中在拦截器和业务层之间共享用户上下文

Spring security 在SpringOAuth2(sso应用程序)中在拦截器和业务层之间共享用户上下文,spring-security,spring-security-oauth2,spring-oauth2,Spring Security,Spring Security Oauth2,Spring Oauth2,从Spring user和oauth2的大量示例中,我遇到了一个问题,但在一些基本概念上仍然失败,也许有人能给我指出一些好的方向/示例或阅读的信息 因此,我正在尝试构建一个基于rest的API应用程序。 为了访问端点,它们将受到JWT令牌的保护,其思想是该令牌用于跨多个其他应用程序的SSO 我最初的想法是使用一些身份验证过滤器拦截器来处理令牌,这样我就可以存储我可能需要的任何附加信息,然后在我的服务的实际业务层中使用该用户。 我已经实现了一些实现过滤器的AuthenticationFiler 我

从Spring user和oauth2的大量示例中,我遇到了一个问题,但在一些基本概念上仍然失败,也许有人能给我指出一些好的方向/示例或阅读的信息

因此,我正在尝试构建一个基于rest的API应用程序。 为了访问端点,它们将受到JWT令牌的保护,其思想是该令牌用于跨多个其他应用程序的SSO

我最初的想法是使用一些身份验证过滤器拦截器来处理令牌,这样我就可以存储我可能需要的任何附加信息,然后在我的服务的实际业务层中使用该用户。 我已经实现了一些实现过滤器的AuthenticationFiler 我可以在从我的令牌存储读取令牌访问后获得附加信息

现在我的第一个问题开始了,事实上,大多数示例都是从登录/注销页面开始的,因为我有更多的API设置,所以我真的没有这个流程

其次,似乎大多数情况下,获取用户的方法都是从主体(SecurityContextHolder.getContext().getAuthentication().getPrinciple())获取,类似这样的内容,但我的主体始终为null,不确定这是否是因为我不知道这是因为有状态还是无状态或排序

因此,我最大的问题是理解如何在安全拦截器和业务层之间共享用户详细信息。也许这些问题并不是关于春天本身的,我缺少更多的基本知识,但也许有人能给我一些建议

这是我的身份验证过滤器,我想知道的是如何创建一个用户实例,就像使用MDC存储用户信息一样。 理想情况下,我希望在那里创建一个用户实例,并将其传递给业务层。我可以用自动连线吗

@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class AuthenticationFilter implements Filter {

  @Autowired
  TokenStore tokenStore;

  @Autowired
  JwtAccessTokenConverter accessTokenConverter;


  @Override
  public void init(FilterConfig filterConfig) {

  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication != null) {
      if (authentication instanceof OAuth2Authentication) {
        OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) authentication;
        OAuth2AuthenticationDetails oauth2AuthenticationDetails = (OAuth2AuthenticationDetails)oAuth2Authentication.getDetails();
        OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(oauth2AuthenticationDetails.getTokenValue());
        Object decodedDetails = oauth2AuthenticationDetails.getDecodedDetails();
        Map<String, Object> additionalInformation = oAuth2AccessToken.getAdditionalInformation();
        MDC.put("sub", additionalInformation.get("sub").toString());
        MDC.put("preferred_username", additionalInformation.get("preferred_username").toString());
      }
    }
    try {
      chain.doFilter(request, response);
    }
    finally {
      MDC.remove("sub");
      MDC.remove("preferred_username");
    }
  }

  @Override
  public void destroy() {

  }
}
@组件
@顺序(有序。最低优先级)
公共类AuthenticationFilter实现筛选器{
@自动连线
代币店代币店;
@自动连线
JwtAccessTokenConverter-accessTokenConverter;
@凌驾
public void init(FilterConfig FilterConfig){
}
@凌驾
public void doFilter(ServletRequest请求、ServletResponse响应、FilterChain链)抛出IOException、ServletException{
身份验证=SecurityContextHolder.getContext().getAuthentication();
if(身份验证!=null){
if(OAuth2Authentication的身份验证实例){
OAuth2Authentication OAuth2Authentication=(OAuth2Authentication)身份验证;
OAuth2AuthenticationDetails OAuth2AuthenticationDetails=(OAuth2AuthenticationDetails)oAuth2Authentication.getDetails();
OAuth2AccessToken OAuth2AccessToken=tokenStore.readAccessToken(oauth2AuthenticationDetails.getTokenValue());
Object decodedDetails=oauth2AuthenticationDetails.getDecodedDetails();
Map additionalInformation=oAuth2AccessToken.getAdditionalInformation();
MDC.put(“sub”,additionalInformation.get(“sub”).toString();
MDC.put(“首选用户名”,additionalInformation.get(“首选用户名”).toString();
}
}
试一试{
链式过滤器(请求、响应);
}
最后{
MDC.移除(“子”);
MDC.删除(“首选用户名”);
}
}
@凌驾
公共空间销毁(){
}
}
不确定这是否是我的误解,但我认为我在寻找的是依赖注入

不知何故,我想创建一个新的用户Bean,将它填入我的过滤器中,然后在其他地方使用它。 我想我可以在我的业务层中使用@autowire,然后在过滤器中设置它,然后在业务层中使用它?
这是一种糟糕的模式吗?

据我所知,您正在开发以下架构:

  • RESTAPI,它应该受到JWT的保护
你想要这个:

  • 访问在业务层的传入JWT中接收的用户信息
如果以上两个假设都是正确的,那么您应该了解spring在其微服务架构中是如何做到这一点的。请阅读以下快速入门:


希望这有帮助。

在此处共享您的身份验证筛选代码。我不确定这样做是否会有帮助谢谢您的反馈我想要的是与您提到的类似的东西,然后结合类似的东西我最终做了类似的事情,我创建了我的用户上下文组件,然后我将其限制在会话范围内。然后,我将其自动连接到身份验证过滤器,然后连接到业务层。似乎是这样trick@MiguelCosta-我也有同样的问题,如果您同意的话,您能分享您的代码片段片段或github repo吗?@bijayshrestha您希望我分享哪些部分?最后,我通过继续阅读和这里发布的示例来做到这一点,但长话短说,我有我的过滤器来处理令牌并验证它。然后,我创建了一个使用“RequestScope”注释存储的用户上下文,最终您可以将上下文自动连接到您想要使用它的位置。