spring-security icon indicating copy to clipboard operation
spring-security copied to clipboard

Improve the documentation for baseUri(..) of oauth2Login.redirectionEndpoint

Open xak2000 opened this issue 2 years ago • 3 comments

Expected Behavior

Usually term baseUri means an URI prefix. E.g. in oauth2Login.authorizationEndpoint configurer there is baseUri(..) method that actually sets base URI of the autorization endpoint. OAuth2AuthorizationRequestRedirectFilter will match all valid URI against the processed URI (using OAuth2AuthorizationRequestResolver), so the filter will handle all valid URIs. No problems here.

On the other hand, baseUri(..) method of the oauth2Login.redirectionEndpoint does totally different thing. I was forced to read many internal framework code to understand what this method actually expects as a parameter. The default value in OAuth2LoginAuthenticationFilter is /login/oauth2/code/* and it is used as AntPathRequestMatcher to determine whether this filter should attempt to process a login request. So, this is not base URI, as a common term we all know, but an ant pattern to use for matching.

Ideally this method should not be named baseUri in the first place, but renaming would be a breaking change, right?

But, at least we could improve the documentation by adding explicit mentioning of the fact that the parameter is the ant pattern of URI and not "URI" and especially not "base URI" (that documentation doesn't say already, but the method name is still misleading, so you read the method name and automatically think that parameter is a "base URI", especially if you already used authorizationEndpoint.baseUri that works as expected).

Current Behavior

Look at this sample:

@Order(1)
@Bean
public SecurityFilterChain apiDocSecurityFilterChain(HttpSecurity http) throws Exception {
	return http
			.securityMatcher("/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**")
			.authorizeHttpRequests(authorize -> authorize
					.anyRequest().authenticated()
			)
			.oauth2Login(oauth2Login -> oauth2Login
					.authorizationEndpoint(authorization -> authorization
							.baseUri("/swagger-ui/oauth2/authorization") // Works fine even though "/swagger-ui/oauth2/authorization" is a partial URL path
					)
					.redirectionEndpoint(redirection -> redirection
							.baseUri("/swagger-ui/login/oauth2/code") // Will not work without "/*" at the end
					)
			)
			.build();
}

// ...other SecurityFilterChains

And the config:

spring.security.oauth2.client.registration.google.redirect-uri={baseUrl}/swagger-ui/login/oauth2/code/{registrationId}

I spent many hours of debugging in attempt to understand why after redirect to /swagger-ui/login/oauth2/code/google browser received 302 and gets redirected back to the /swagger-ui/oauth2/authorization. I tried to unsecure the redirection endpoint and was surprised by response 404. Then I realized that no filter handles the the baseUri I set (/swagger-ui/login/oauth2/code). The reason was found only by carefully inspecting the implementation details.

Context

I think the context is not important in this case, but I'll mention it anyway.

For the specific task I worked on it is important to have all filters to sit under /swagger-ui/** pattern as this is the only resource that should be handled by OAuth2Login in the application, while other APIs should not. That is why I tried to set baseUri of redirectionEndpoint.

Aside note: When I tried to solve this task I found that I can't change the /login URL (the URL that is handled by default filter that renders the login page). I can set a custom login URL, but this is not my intention. My intention is to not implement any custom login pages, but use default login page. I know it is not intended to be used in producion etc., but my use case is secure swagger-ui, so only DEVs will see this page. The default page is enough for this case. And I need to change the URL to make it sit under /swagger-ui/** pattern because the whole security filter chain should listen only this pattern and not leak to other URLs to prevent interfere with other security filter chains. But probably this deserves a separate github issue.

xak2000 avatar May 31 '23 16:05 xak2000

@xak2000 Thanks a lot for the above information that helps me understand the process. I am not sure if it is appropriate for me to post here with my similar issue mentioned at https://stackoverflow.com/questions/77643991/spring-security-oauth2-404-not-found-for-redirect-url-login-oauth2-code-azure I am stuck at the issue and not sure if in a right direction.

  • I am using the method mentioned in https://github.com/spring-projects/spring-security/issues/11108 to mix my existing XML config and the above Java OAuth2SecurityConfig.

  • From catalina.log, I could see OAuth2LoginAuthenticationFilter in the Security filter chain.

I always got 404 with the authorization code /login/oauth2/code/azure?code=###, by reading above, I suspect it is not intercepted by the OAuth2LoginAuthenticationFilter. All of my contents are under http://localhost:8080/context-path/, so I use baseUri("/login/oauth2/code/*") and redirectUri("{baseUrl}/login/oauth2/code/{registrationId}") for ClientRegistration

qch1866 avatar Dec 13 '23 05:12 qch1866

I would agree with this, the documentation is confusing and lacking in examples for instance: 2 oauth2 providers both with non-standard redirect-uri’s

veganchamp avatar Mar 21 '24 15:03 veganchamp

I agree as well. That is very misleading and confusing.

dabkowski avatar May 23 '24 17:05 dabkowski