Spring security 如何在Spring Security中动态指定OAuth2资源详细信息?

Spring security 如何在Spring Security中动态指定OAuth2资源详细信息?,spring-security,oauth,shopify,spring-security-oauth2,Spring Security,Oauth,Shopify,Spring Security Oauth2,我正在创建一个与Shopify的API集成的应用程序,它使用OAuth2进行身份验证和授权。使用,并且,我已经能够与单个商店进行集成。YAML配置如下所示: shopify: shop: myshop scopes: read_customers,read_orders security: oauth2: client: clientId: myclientid clientSecret: mysecret tokenName: acces

我正在创建一个与Shopify的API集成的应用程序,它使用OAuth2进行身份验证和授权。使用,并且,我已经能够与单个商店进行集成。YAML配置如下所示:

shopify:
  shop: myshop
  scopes: read_customers,read_orders
security:
  oauth2:
    client:
      clientId: myclientid
      clientSecret: mysecret
      tokenName: access_token
      authenticationScheme: query
      clientAuthenticationScheme: form
      accessTokenUri: https://${shopify.shop}.myshopify.com/admin/oauth/access_token
      userAuthorizationUri: https://${shopify.shop}.myshopify.com/admin/oauth/authorize?scope=${shopify.scopes}&grant_options[]=
      pre-established-redirect-uri: https://myapp/login
      registered-redirect-uri: https://myapp/login
      use-current-uri: false
    resource:
      userInfoUri: https://${shopify.shop}.myshopify.com/admin/shop.json
但是,此静态配置不适用于Shopify应用商店中发布的应用,因为重定向、访问令牌、用户信息和用户授权URI取决于商店名称,但它们仍然必须是静态的

为了使这些URI是动态的,我提出了几个可能的选项:

  • 使用
    /login
    路径中的一个参数来标识店铺,然后创建一个过滤器,将店铺名称添加到运行在其他所有内容之前的
    ThreadLocal
    ,然后通过Spring代理的工厂bean动态创建OAuth2过滤器所需的
    AuthorizationCodeResourceDetails

  • 使用一种“元过滤器”,动态地为每个请求重新创建
    OAuth2ClientAuthenticationProcessingFilter
    ,以及它所需的所有资源

  • 重写OAuth2ClientAuthenticationProcessingFilter,以便它能够处理重新创建获取访问令牌所需的
    RestTemplate

  • 所有这些选择似乎都相当困难。在SpringSecurityOAuth2中,处理访问令牌和用户信息的动态生成URI的好方法是什么


    另外,由于我通常是OAuth2新手,我是否需要在Spring配置中启用资源服务器以使用访问令牌保护我的应用程序?

    有点晚,但我确实通过覆盖Oauth2ProtectedResource的getter返回了oauth资源的动态url

        @Bean(name = "googleOauthResource")
    public BaseOAuth2ProtectedResourceDetails getGoogleOauthResource() {
        final AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails() {
            @Override
            public String getPreEstablishedRedirectUri() {
                final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
                if (requestAttributes instanceof ServletRequestAttributes) {
                    final HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
                    return request.getRequestURL() + "?" + request.getQueryString() + "&addStuff";
                }
    
                return super.getPreEstablishedRedirectUri();
            }
        };
        details.setId("google-oauth-client");
        details.setClientId("xxxxxxxxxxx");
        details.setClientSecret("xxxxxxxx");
        details.setAccessTokenUri("https://www.googleapis.com/oauth2/v4/token");
        details.setUserAuthorizationUri("https://accounts.google.com/o/oauth2/v2/auth");
        details.setTokenName("authorization_code");
        details.setScope(Arrays.asList("https://mail.google.com/,https://www.googleapis.com/auth/gmail.modify"));
        details.setPreEstablishedRedirectUri("http://localhost:8080/xxx-api-web/v2/gmail"); //TODO
        details.setUseCurrentUri(false);
        details.setAuthenticationScheme(AuthenticationScheme.query);
        details.setClientAuthenticationScheme(AuthenticationScheme.form);
        details.setGrantType("authorization_code");
        return details;
    }
    

    我遇到了与您相同的问题,我倾向于您使用ThreadLocal存储的第一个理论。以下是我可能会采取的解决方案:

    通过覆盖OAuth2ClientAuthenticationProcessingFilter中的方法,从LocalThread存储中的ServletRequest设置值:

    • 尝试验证
    • 成功的身份验证
    • 身份验证失败
    • 要求重新认证
    然后通过重写以下方法在OAuth2RestTemplate中转换URI:

    • 创建请求
    • 多谢
    • 附录参数
    我可能必须为RestTemplate创建自己的@Bean,该RestTemplate有一个注入的@Service,用于查找动态Shopify域


    如果我的解决方案有效,我会发布。

    Hi@Brad,我也有类似的问题。你知道怎么做了吗?很遗憾,只是理论上的。这需要对图书馆的工作方式进行一些相当重大的改变;
    @enableAuthSSO
    注释提供给您的内容实际上只适用于静态站点。您必须创建新的类并连接bean以实现不同的功能。我也在寻找答案。你有什么进展吗?我看看能不能把东西拼起来。现在不行。我一直在努力让Spring Security给我一位负责人提供我需要的Shopify信息(比如商家名称),所以我没有时间看这个。