【问题标题】:How to change response_type on Spring OAuth2如何在 Spring OAuth2 上更改 response_type
【发布时间】:2017-05-03 15:41:56
【问题描述】:

这是我使用 Instagram 进行 OAuth2 登录的配置

instagram:
  client:
    clientId: clientId
    clientSecret: clientSeret
    accessTokenUri: https://api.instagram.com/oauth/access_token
    userAuthorizationUri: https://api.instagram.com/oauth/authorize
    clientAuthenticationScheme: form
  scope:
    - basic
    - public_content
  resource:
    userInfoUri: https://api.instagram.com/v1/users/self/
    delimiter: +

这是 Spring 发出的请求:

https://api.instagram.com/oauth/authorize?client_id=clientId&redirect_uri=http://localhost:8080/login/instagram&response_type=code&state=CG6mMQ

如何将 response_type 更改为 &response_type=token 以及为什么 Spring 不添加范围?

这是 App 类:

@SpringBootApplication
@EnableOAuth2Client
public class App extends WebSecurityConfigurerAdapter {

    @Autowired
    OAuth2ClientContext oauth2ClientContext;

    public static void main(String[] args) throws Exception {
        SpringApplication.run(App.class, args);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/", "/login**", "/webjars/**")
                .permitAll()
                .anyRequest()
                .authenticated().and().exceptionHandling()
                .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/"))
                // logout
                .and().logout().logoutSuccessUrl("/").permitAll()
                // CSRF
                .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                // filters
                .and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
    }

    private Filter ssoFilter() {
        CompositeFilter filter = new CompositeFilter();
        List<Filter> filters = new ArrayList<>();

        // facebook ...
        // google ...

        // instagram
        OAuth2ClientAuthenticationProcessingFilter instagramFilter =
                new OAuth2ClientAuthenticationProcessingFilter("/login/instagram");
        OAuth2RestTemplate instagramTemplate =
                new OAuth2RestTemplate(instagram(), oauth2ClientContext);
        instagramFilter.setRestTemplate(instagramTemplate);
        instagramFilter.setTokenServices(
                new UserInfoTokenServices(instagramResource().getUserInfoUri(), instagram().getClientId()));
        filters.add(instagramFilter);

        filter.setFilters(filters);
        return filter;
    }

    @Bean
    @ConfigurationProperties("instagram.client")
    public AuthorizationCodeResourceDetails instagram() {
        return new AuthorizationCodeResourceDetails();
    }

    @Bean
    @ConfigurationProperties("instagram.resource")
    public ResourceServerProperties instagramResource() {
        return new ResourceServerProperties();
    }

    @Bean
    public FilterRegistrationBean oauth2ClientFilterRegistration(
            OAuth2ClientContextFilter filter) {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(filter);
        registration.setOrder(-100);
        return registration;
    }
}

【问题讨论】:

    标签: spring spring-boot spring-security


    【解决方案1】:

    如何将 response_type 更改为 &response_type=token

    当我阅读代码时,AuthorizationCodeAccessTokenProvider‘s response_type 是硬代码。

    private UserRedirectRequiredException getRedirectForAuthorization(AuthorizationCodeResourceDetails resource,
                AccessTokenRequest request) {
    
            // we don't have an authorization code yet. So first get that.
            TreeMap<String, String> requestParameters = new TreeMap<String, String>();
            requestParameters.put("response_type", "code"); // oauth2 spec, section 3
    

    所以,如果你想改变response_code,你可以扩展AuthorizationCodeAccessTokenProvider,或者实现AccessTokenProvider,然后注入到OAuth2RestTemplateaccessTokenProvider(默认值是一个AccessTokenProviderChain,其中包含AuthorizationCodeAccessTokenProviderResourceOwnerPasswordAccessTokenProvider 等等,使用你自己的提供者而不是 AuthorizationCodeAccessTokenProvider)。

    或者你可以把OAuth2ClientContextFilter里面的redirectStrategy改成重定向时的request参数,但是我不推荐这样做。

    我怎么能不 Spring 添加范围?

    AuthorizationCodeAccessTokenProvider 将从AuthorizationCodeResourceDetails 获取范围,并将它们添加到UserRedirectRequiredException。我认为范围不能注入AuthorizationCodeResourceDetails,因为范围不在客户端下。也许你需要改变这个。

    instagram:
      client:
        clientId: clientId
        clientSecret: clientSeret
        accessTokenUri: https://api.instagram.com/oauth/access_token
        userAuthorizationUri: https://api.instagram.com/oauth/authorize
        clientAuthenticationScheme: form
        scope:
          - basic
          - public_content
    

    【讨论】:

      【解决方案2】:

      您可以从UserRedirectRequiredException 访问查询参数。因此,在引发异常并因此导致重定向发生的代码中,例如在您的过滤器中,您可以执行以下操作:

      try {
          accessToken = restTemplate.getAccessToken();
      }
      catch (UserRedirectRequiredException e) {
          Map<String, String> requestParams = e.getRequestParams();
          requestParams.put("response_type", "token");
      
          throw e; //don't forget to rethrow
      }
      

      您只能以这种方式替换值。如果您需要在现有值旁边添加参数值,则需要使用分隔符,例如“+”。没有添加多个参数值的标准方法,这取决于 API 的所有者接受的内容。有些 API 可能根本不接受分隔符。

      【讨论】:

        猜你喜欢
        • 2021-04-11
        • 1970-01-01
        • 2019-01-21
        • 1970-01-01
        • 2019-06-03
        • 2014-03-31
        • 2014-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多