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

Bra*_*rad 5 oauth spring-security shopify spring-security-oauth2

我正在创建一个与Shopify的API集成的应用程序,该API使用OAuth2进行身份验证和授权。使用了Spring Security的OAuth2用户的教程,和教程的Shopify,我已经能够得到整合工作与单店。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
Run Code Online (Sandbox Code Playgroud)

但是,此静态配置不适用于在Shopify的App Store中发布的应用程序,因为重定向,访问令牌,用户信息和用户授权URI取决于商店名称。 有使用多个提供程序的示例,但是它们仍然必须是静态的。

为了使这些URI动态,我提出了一些可能的选择:

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

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

  3. 重写,OAuth2ClientAuthenticationProcessingFilter以便它可以处理重新创建RestTemplate获取访问令牌所需的操作。

所有这些选项似乎都很困难。在Spring Security OAuth2中处理访问令牌和用户信息的动态生成的URI的好方法是什么?

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

edu*_*ayo 2

有点晚了,但我确实通过覆盖 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;
}
Run Code Online (Sandbox Code Playgroud)