-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
URL-encoded parameters in redirect URI are encoded twice #1011
Conversation
… authorization response The redirect URI used in the test contains a URL-encoded parameter and is similar to redirect URIs of the popular Yii PHP framework. Also document how state is currently decoded and re-encoded, modifying it in the process.
…response Redirect URIs can contain query parameters and these can be URI encoded. UriComponentsBuilder does not decode query parameters in fromUriString(). They become part of the template which by default is encoded (again). This commit configures a UriBuilder that does not encode the template but only provided values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR @andreasf ! Please see review comments.
@@ -39,6 +39,18 @@ public static RegisteredClient.Builder registeredClient() { | |||
.scope("scope1"); | |||
} | |||
|
|||
public static RegisteredClient.Builder registeredClientEncodedUri() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this and leverage the existing TestRegisteredClients.registeredClient()
and add the url-encoded redirect-uri
@@ -8,6 +8,10 @@ group = project.rootProject.group | |||
version = project.rootProject.version | |||
sourceCompatibility = "17" | |||
|
|||
test { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert all changes in custom-consent-authorizationserver
since we have test coverage in default-authorizationserver
and there is no need to duplicate
@@ -8,6 +8,10 @@ group = project.rootProject.group | |||
version = project.rootProject.version | |||
sourceCompatibility = "17" | |||
|
|||
test { | |||
useJUnitPlatform() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be removed since it's automatically applied by the SpringJavaPlugin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent quite a while figuring out why the tests don't run locally and in CI, in my opinion this config should have been added in the "Upgrade to JUnit 5" commit.
Did you try it out and are tests running (and failing the build) on your machine without explicitly enabling JUnit 5?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that the samples do not use the io.spring.convention.spring-module
plugin, so SpringJavaPlugin
is not applied as I previously mentioned. Sorry for the confusion there.
However, I'm wondering why the tests are failing on your end? The tests in default-authorizationserver
sample are passing locally and in CI for quite some time now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't make myself fully clear. The tests are not failing in their current state.
What I meant was: if Gradle says the build was successful, that does not necessarily mean that it ran tests. To check if it does, I like to make a test fail, e.g. by throwing a RuntimeException. The failing test should also lead to a failing build.
For CI, I checked the logs of several commits for the test output – I think there's a DB-related message. This message did not appear after the upgrade to JUnit 5.
@@ -87,6 +87,7 @@ public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTe | |||
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) | |||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) | |||
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc") | |||
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc?param=is%2Fencoded") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's change is%2Fencoded
to encoded%20parameter%20value
|
||
private static final String AUTHORIZATION_REQUEST = UriComponentsBuilder | ||
.fromPath("/oauth2/authorize") | ||
.queryParam("response_type", "code") | ||
.queryParam("client_id", "messaging-client") | ||
.queryParam("scope", "openid") | ||
.queryParam("state", "some-state") | ||
.queryParam("redirect_uri", REDIRECT_URI) | ||
.queryParam("state", STATE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert all changes related to the state
parameter since this was fixed in gh-875 and test coverage is included in the associated commit
@@ -67,6 +74,16 @@ public void setUp() { | |||
this.webClient.getCookieManager().clearCookies(); // log out | |||
} | |||
|
|||
@Test | |||
void authorizationRequestProperlyEncoded() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this test since it directly tests UriComponentsBuilder
, which is not owned by this project.
@@ -83,7 +83,7 @@ | |||
public class OAuth2AuthorizationEndpointFilterTests { | |||
private static final String DEFAULT_AUTHORIZATION_ENDPOINT_URI = "/oauth2/authorize"; | |||
private static final String AUTHORIZATION_URI = "https://provider.com/oauth2/authorize"; | |||
private static final String STATE = "state"; | |||
private static final String STATE = "previously encoded/state"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert all changes related to the state
parameter since this was fixed in gh-875 and test coverage is included in the associated commit
@@ -58,15 +62,18 @@ public class DefaultAuthorizationServerConsentTests { | |||
@MockBean | |||
private OAuth2AuthorizationConsentService authorizationConsentService; | |||
|
|||
private final String redirectUri = "http://127.0.0.1/login/oauth2/code/messaging-client-oidc"; | |||
private final String redirectUri = "http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc?param=is%2Fencoded"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert all changes in DefaultAuthorizationServerConsentTests
since we have same test coverage in DefaultAuthorizationServerApplicationTests
@andreasf Just checking back to see if you're able to apply the requested changes? |
I'm a bit busy but I'll try to take a look this week |
@andreasf We have a release next week and I wanted to get this fix in so I went ahead and added a polish commit and merged. |
This fixes an issue with redirect URIs that already have URL-encoded parameters baked in.
I recently built an OIDC provider with Authorization Server for a client and noticed that some of their redirect URIs would cause problems.
PHP's Yii framework creates redirect URIs in the format
https://example.com/index.php?r=site%2Fauth&authclient=foo
. The authorization endpoint would reencode the%2F
in the parameter to%252F
and redirect users to a non-existing route.This PR fixes the behavior while making sure that the encoding of the state parameter is unchanged.
Related to #875