5

我想要做的是在openid.realm我的授权请求中添加一个额外的参数。

我的问题与https://github.com/spring-projects/spring-security-oauth/issues/123非常相似,我尝试按照概述的方式解决它:

// Create an enhancer that adds openid.realm
DefaultRequestEnhancer enhancer = new DefaultRequestEnhancer();
enhancer.setParameterIncludes(Arrays.asList("openid.realm"));

// Create tokenprovider that use the enhancer
AuthorizationCodeAccessTokenProvider tokenProvider =
    new AuthorizationCodeAccessTokenProvider();
tokenProvider.setAuthorizationRequestEnhancer(enhancer);

// Give the tokenProvider to the rest template
googleOauthRestTemplate.setAccessTokenProvider(tokenProvider);
googleOauthRestTemplate.
    getOAuth2ClientContext().
        getAccessTokenRequest().set("openid.realm", "http://localhost:8080/");

// Try to get the protected resource
googleOauthRestTemplate.
    getForObject("https://www.googleapis.com/...", String.class);

现在,当用户第一次点击此代码时,他会被抛出UserRedirectRequiredException(源自 getRedirectForAuthorization)并且参数有client_id、和redirect_uri,它们看起来都不错,但我错过了我刚刚设置的参数。response_typescopeopenid.realm

它不应该在重定向期间也存在吗?

更新:

这是一个在最后一个断言上失败的新测试用例。(放入文件AuthorizationCodeAccessTokenProviderTests.java:)

@Test
public void testEnhancedRedirectToAuthorizationEndpoint() throws Exception {
    DefaultRequestEnhancer enhancer = new DefaultRequestEnhancer();
    enhancer.setParameterIncludes(Arrays.asList("openid.realm"));

    provider.setAuthorizationRequestEnhancer(enhancer);

    AccessTokenRequest request = new DefaultAccessTokenRequest();
    request.set("openid.realm", "http://localhost:8080");
    request.setCurrentUri("/come/back/soon");
    resource.setUserAuthorizationUri("http://localhost/oauth/authorize");

    try {
        provider.obtainAccessToken(resource, request);
        fail("Expected UserRedirectRequiredException");
    }
    catch (UserRedirectRequiredException e) {
        assertEquals("http://localhost/oauth/authorize", e.getRedirectUri());
        assertEquals("/come/back/soon", e.getStateToPreserve());
        assertEquals("code", e.getRequestParams().get("response_type"));
        assertEquals("http://localhost:8080", e.getRequestParams().get("openid.realm"));
    }
}

更新 2: 我通过扩展令牌提供程序并手动添加参数来解决这个问题。也许它不是正确的方法,但它似乎至少适用于我的具体情况:

class EnhancedAuthorizationCodeAccessTokenProvider extends AuthorizationCodeAccessTokenProvider {
    static String REQUEST_PARAM_OPENID_REALM = "openid.realm";

    @Override
    public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails details, AccessTokenRequest request) throws UserRedirectRequiredException, UserApprovalRequiredException, AccessDeniedException, OAuth2AccessDeniedException {
        try {
            return super.obtainAccessToken(details, request);
        } catch (UserRedirectRequiredException e) {
            Map<String, String> requestParams = e.getRequestParams();
            if (!requestParams.containsKey(REQUEST_PARAM_OPENID_REALM) && request.containsKey(REQUEST_PARAM_OPENID_REALM)) {
                requestParams.put(REQUEST_PARAM_OPENID_REALM, request.getFirst(REQUEST_PARAM_OPENID_REALM));
            }

            throw e;
        }
    }
}
4

0 回答 0