使用Spring Security OAuth2刷新令牌为空

时间:2015-02-25 14:36:46

标签: java spring spring-security oauth-2.0

我正在尝试使用Spring Security集成Google OAuth 2。一切正常,但refresh_token为空。

这是我的配置:

@Bean
public OAuth2ProtectedResourceDetails googleOAuth2Details() {
    AuthorizationCodeResourceDetails googleOAuth2Details = new AuthorizationCodeResourceDetails();
    googleOAuth2Details.setAuthenticationScheme(form);
    googleOAuth2Details.setClientAuthenticationScheme(form);
    googleOAuth2Details.setClientId(googleClientId);
    googleOAuth2Details.setClientSecret(googleClientSecret);
    googleOAuth2Details.setUserAuthorizationUri(googleOAuthUri);
    googleOAuth2Details.setAccessTokenUri(googleTokenUrl);
    googleOAuth2Details.setScope(asList("openid","email"));
    return googleOAuth2Details;
}

我读到为了获得refresh_token,access_type必须是“离线”。但是在Spring中设置它的方法是什么?

3 个答案:

答案 0 :(得分:1)

我担心' access_type '参数不在OAUTH2 Authorization (RFC 6749)范围内,而Spring默认没有它,所以你需要手动添加它。不幸的是,我现在没有正确的方法,但我认为' OAuth2RestTemplate#getAccessToken '是开始调查的好地方。

同样this post可能对您有用。

答案 1 :(得分:1)

试试这个:你可以将参数“hard-configured”添加到googleOAuthUri,所以:

googleOAuthUri = googleOAuthUri + "?access_type=offline";
googleOAuth2Details.setUserAuthorizationUri(googleOAuthUri);

并且希望Spring在添加其他参数时做正确的事。

另请注意,refresh_token仅在用户首次授予您的客户端访问权限时返回。后续授权请求不会产生新的refresh_token,因为假设您的客户端已经存储了第一个请求。

答案 2 :(得分:0)

您可以创建OAuth2AuthorizationRequestResolver的自定义实现,并按照Spring security documentation所述将additionalParameters(..)"access_type"="offline"添加在一起。

@EnableWebSecurity
public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
    private final ClientRegistrationRepository clientRegistrationRepository;

    public OAuth2LoginSecurityConfig(ClientRegistrationRepository clientRegistrationRepository) {
        this.clientRegistrationRepository = clientRegistrationRepository;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .oauth2Login()
                .authorizationEndpoint()
                .authorizationRequestResolver(
                        new CustomAuthorizationRequestResolver(
                                this.clientRegistrationRepository));
    }
}

public class CustomAuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {
    private final OAuth2AuthorizationRequestResolver defaultAuthorizationRequestResolver;

    public CustomAuthorizationRequestResolver(ClientRegistrationRepository clientRegistrationRepository) {
        this.defaultAuthorizationRequestResolver = new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository, OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI);
    }

    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
        final OAuth2AuthorizationRequest authorizationRequest = this.defaultAuthorizationRequestResolver.resolve(request);
        return authorizationRequest != null ? customAuthorizationRequest(authorizationRequest) : null;
    }

    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId) {
        final OAuth2AuthorizationRequest authorizationRequest = this.defaultAuthorizationRequestResolver.resolve(request, clientRegistrationId);
        return authorizationRequest != null ? customAuthorizationRequest(authorizationRequest) : null;
    }

    private OAuth2AuthorizationRequest customAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest) {
        Map<String, Object> additionalParameters = new LinkedHashMap<>(authorizationRequest.getAdditionalParameters());
        additionalParameters.put("access_type", "offline");
        return OAuth2AuthorizationRequest.from(authorizationRequest)
                .additionalParameters(additionalParameters)
                .build();
    }
}