in china, some oauth provider's implementation is not standard enough
for example wechat, it use appid instead of client_id and must add url hash #wechat_redirect
can we add more customization for OAuth2AuthorizationRequest and OAuth2AuthorizationRequestResolver
@okhowang You can customize the OAuth2AuthorizationRequest by supplying a custom OAuth2AuthorizationRequestResolver. See the reference doc for an example.
You can also customize the Token Request.
I'm going to close this issue as I feel I answered your question.
OAuth2AuthorizationRequestResolver has many common logic, for example pkcs and so on.
i just want use OAuth2AuthorizationRequestResolver and customizer OAuth2AuthorizationRequest.Builder
@okhowang I'm not sure I understand your request. Can you provide a more detailed explanation or even a code sample of what you would like to accomplish?
for example, when call with a standard oauth provider
spring security will redirect to url like https://some.domain.com/authorize?client_id=foo&scope=bar&response_type=code&redirect_uri=https://some.url/
but in wechat it will be https://some.domain.com/authorize?appid=foo&scope=bar&response_type=code&redirect_uri=https://some.url/#wechat_redirect
of course, i can customize OAuth2AuthorizationRequestResolver to do this.
but i also need other standard oauth provider
I want reuse spring's OAuth2AuthorizationRequestResolver class, and just customize OAuth2AuthorizationRequest.Builder's logic which determine redirect url directly.
I don't want modify any in OAuth2AuthorizationRequestResolver except OAuth2AuthorizationRequest.Builder
Ok I understand now.
So let's say we add DefaultOAuth2AuthorizationRequestResolver.setAuthorizationRequestConsumer(Consumer<OAuth2AuthorizationRequest.Builder> builderConsumer). This will allow you to supply a Consumer and hook into the build process.
However, it still will not let you change the parameter names. You need to change client_id to appid but the Consumer will only allow you to override the parameter values. If you want to change the parameter names than you need to use the delegation-based strategy. Does this make sense or am I missing something?
final redirect uri is make by OAuth2AuthorizationRequest.Builder#buildAuthorizationRequestUri
I write a builder which use a parameterNameMap to map oauth2 original parameterName to provider's parametersName now
private fun set(map: MultiValueMap<String, String>, name: String, value: String) {
map[parameterNameMap[name] ?: name] = value
}
private fun buildAuthorizationRequestUri(): String {
val parameters = LinkedMultiValueMap<String, String>()
set(parameters, OAuth2ParameterNames.RESPONSE_TYPE, this.responseType.value)
set(parameters, OAuth2ParameterNames.CLIENT_ID, this.clientId)
scopes?.let { set(parameters, OAuth2ParameterNames.SCOPE, it.joinToString(" ")) }
state?.let { set(parameters, OAuth2ParameterNames.STATE, it) }
redirectUri?.let { set(parameters, OAuth2ParameterNames.REDIRECT_URI, it) }
additionalParameters?.let { it.forEach { (key, value) -> parameters.set(key, value.toString()) } }
return UriComponentsBuilder.fromHttpUrl(this.authorizationUri)
.queryParams(parameters)
.fragment(clientRegistration.authorizationHash()) // add custom fragment
.encode(StandardCharsets.UTF_8)
.build()
.toUriString()
}
@okhowang I just submitted #7748. Please see this test, which should handle your use case. Please let me know if this will work for you.
In parameters, it looks like ok
but how to it for url segment, aka hash? or more?
we may not need a Consumer for OAuth2AuthorizationRequest.Builder
a interface for OAuth2AuthorizationRequest.Builder may be better?
and we can set a customize implementation of RequestBuilder for DefaultOAuth2AuthorizationRequestResolver
@okhowang
but how to it for url segment, aka hash?
You can update like this:
this.resolver.setAuthorizationRequestCustomizer(customizer -> {
// TODO Append #wechat_redirect (Option 1)
customizer.redirectUri(...);
// TODO Append #wechat_redirect (Option 2)
customizer.parameters(parameters -> {
String redirectUri = (String) parameters.get(OAuth2ParameterNames.REDIRECT_URI);
redirectUri += "#wechat_redirect";
parameters.put(OAuth2ParameterNames.REDIRECT_URI, redirectUri);
});
});
a interface for OAuth2AuthorizationRequest.Builder may be better?
I'm not sure if an interface would be better. I believe a Consumer is simpler.
Do you see any limitations with the Consumer<OAuth2AuthorizationRequest.Builder> approach? If so, please provide specific details so I can understand and improve.
#wechat_redirect need be add on authorizationUri not redirectUri
or builder add a hash optional
like below
this.resolver.setAuthorizationRequestCustomizer(customizer -> {
customizer.hash("wechat_redirect");
});
I thought you need to add to redirect_uri?
but in wechat it will be https://some.domain.com/authorize?appid=foo&scope=bar&response_type=code&redirect_uri=https://some.url/#wechat_redirect
I'm sorry for bad case
in wechat doc it's like https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
ok so #wechat_redirect is appended at the end of URI. Let me see what I can come up with to support this.
@okhowang Take a look at this test. This should fulfill your requirement. Let me know what you think.
LGTM
请问你是如何在authorizationRequestCustomizer中区分标准oauth2 provider与非标准的oauth2 provider?
请问你是如何在authorizationRequestCustomizer中区分标准oauth2 provider与非标准的oauth2 provider?
这个是在OAuth2AuthorizationRequest构造之前就要在业务逻辑里自己确定,然后调用不同的Customizer处理
Most helpful comment
LGTM