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

时间:2018-05-09 06:59:17

标签: spring-security spring-security-oauth2 spring-oauth2

我有一个问题来自于阅读Spring用户和oauth2中的大量示例,但仍然在一些基本概念上失败,也许有人可以指出我的好方向/示例或信息阅读。

所以我正在尝试构建一个基于休息的API应用程序。 要访问端点,它们将受到JWT令牌的保护,并且想法是令牌用于跨多个其他应用程序的SSO。

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

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

其次,似乎大多数时候获取用户的方式来自主体(SecurityContextHolder.getContext()。getAuthentication()。getPrinciple())类似于此但我的主体始终为null,不确定这是否是因为我真的不知道这是因为有状态与无状态还是各种各样。

所以我最大的问题是要了解如何在安全拦截器和业务层之间共享用户详细信息。也许这个问题不是关于春天本身,而是我有更多的基本知识缺失,但也许有人可以给我一些指示。

这是我的身份验证过滤器,我想知道的是如何创建用户实例的方式与使用MDC存储用户信息的方式相同。 理想情况下,我想在那里创建一个用户实例,然后将其传递给业务层。我可以用Autowire做到吗?

@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() {

  }
}

不确定这是否是我的错误理解,但我认为我正在寻找的是依赖注射。

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

1 个答案:

答案 0 :(得分:1)

据我了解你的架构,你正在开发这个:

  • Rest API,应受JWT保护。

你想要这个:

  • 访问业务层中传入JWT中收到的用户信息。

如果上述两个假设都是正确的,那么你应该在它的微服务架构中阅读spring如何做到这一点。阅读本文以便快速入门:

https://dzone.com/articles/json-web-tokens-with-spring-cloud-microservices

希望这有帮助。