【问题标题】:Spring Oauth with multiple users tables具有多个用户表的 Spring Oauth
【发布时间】:2017-08-31 14:47:36
【问题描述】:

我正在使用带有 Oauth2 的 Spring 创建一个应用程序作为两个应用程序(提供者应用程序和一个消费者应用程序)的后端。我有两种不同类型的用户;提供者和消费者,每个都有自己的数据库表。 我面临的问题是我找不到一种方法来知道请求是来自提供商还是客户,因为每个请求都在不同的数据库表中。

用户名在两个表之间不是唯一的。因此,提供者和消费者可以拥有相同的用户名(和密码)。 我认为以下任何一种解决方案都足够了,但是,我找不到任何方法来实现它们。

  • 每个用户类有两个不同的端点。例如“/provider/oauth/token”和“/consumer/oauth/token”。每个都有其自定义身份验证管理器。
  • 或者:在同一个 Spring 应用程序中拥有两个授权服务器,然后将它们的“/oauth/token”映射到不同的端点。
  • 或者:在 oauth 请求中发送自定义数据以了解请求的来源,然后动态选择身份验证管理器。
  • 或者:将不同的身份验证管理器关联到不同的 OAuth 客户端,然后确保每个应用程序都有各自的客户端 ID。

如果这些解决方案中的任何一个是可能的,或者如果有其他方法可以实现这一点,请告诉我。 任何帮助表示赞赏。

编辑 - 解决方案

按照下面的答案,我添加了另一个具有不同客户端 ID 的客户端,检查 UserDetailsS​​ervice 中的 id,然后决定使用哪个数据库。代码如下:

  public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
            UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
            User user = (User) authentication.getPrincipal();
            String username = user.getUsername();
            if (username.equals(OAuth2Configuration.provider_app))
                   // Load from provider db
            else if (username.equals(OAuth2Configuration.consumer_app))
                  // Load from consumer db
            else
                throw new UsernameNotFoundException("ClientID " + username + " not found.");
        }
    };
}

UsernamePasswordAuthenticationToken 被用作 /oauth/token 使用客户端 ID 和密码使用基本 Oauth 进行保护。

【问题讨论】:

    标签: spring oauth oauth-2.0


    【解决方案1】:

    我认为您应该能够查看SecurityContextHolder.getContext().getAuthentication 的内部。 这应该是OAuth2Authentication 的一个实例,您可以(在您投射之后)从中调用getOAuth2Request() 以获取原始Oauth2Request 详细信息。

    有了这些信息,您可以拥有一个UserDetailsService,它可以将查找委托给正确的数据库表。您可以使用范围或 resourceIds 来帮助确定要使用的 db 表。

    【讨论】:

    • 谢谢。您的建议(经过几次修改)对我有用。我在原始问题中发布了代码。
    【解决方案2】:

    您可以使用第三个选项。但这不是一个好的原则。您可以在 oauth/token 端点发送自定义参数。它可以通过 userDetailsS​​ervice 中的 AutoWiring HttpServletRequest 访问。

    用户详细信息服务

    @Autowired
    private HttpServletRequest httpServletRequest;
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            String userType = httpServletRequest.getParameter("user_type");
            LOGGER.info("Load user method \n Username : " + username + "\nuser_type : " + userType);
            if (userType == null) {
                throw new CustomOauthException("User type is required !");
            }
            if (userType.equals(String.valueOf(MOBILE_USER))) {
                //get user..
    
            } else if (userType.equals(String.valueOf(DRIVER))) {
                //get driver..
    
            } else if (userType.equals(String.valueOf(ADMIN))) {
                //get admin
            }
            throw new CustomOauthException("User type is not valid !");
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("Exception : " + e.getMessage());
            throw new CustomOauthException(e.getMessage());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      • 2013-07-28
      • 1970-01-01
      • 2017-03-05
      • 2017-06-14
      • 2016-06-25
      • 2015-03-18
      相关资源
      最近更新 更多