Spring-security-oauth: Changing OAuth2 endpoint mappings only work when the DispatcherServlet is mapped to the root of the context.

Created on 11 Jun 2014  Â·  13Comments  Â·  Source: spring-projects/spring-security-oauth

Create the DispatcherServlet and DelegatingFilterProxy and map to something other than "/"

ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("test-service", new DispatcherServlet(dispatcherContext));
dispatcherServlet.setLoadOnStartup(1);
dispatcherServlet.addMapping("/testservice/*");

DelegatingFilterProxy filter = new DelegatingFilterProxy("springSecurityFilterChain", dispatcherContext);
servletContext.addFilter("springSecurityFilterChain", filter).addMappingForUrlPatterns(null, false, "/testservice/*");

To get the security filter that is configured with @EnableAuthorizationServer to work, it is required to remap the endpoints in a AuthorizationServerConfigurerAdapter

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.pathMapping("/oauth/token", "/testservice/oauth/token");
// ...
}

Changing the mapping also changes the mapping to the handlers to "/testservice/oauth/token" which causes the handlers to be addressable at CONTEXTROOT/testservice/testservice/oauth/token. This is incorrect.

There appears to be no way to change the security filter matchers without also changing the request handler mapping.

Perhaps there is a way to provide an endpoint prefix to the AutorizationServerSecurityConfiguration

String tokenEndpointPath = handlerMapping.getPath("/oauth/token");
String tokenKeyPath = handlerMapping.getPath("/oauth/token_key");
String checkTokenPath = handlerMapping.getPath("/oauth/check_token");
// @formatter:off
http
       .authorizeRequests()
           .antMatchers(tokenEndpointPath).fullyAuthenticated()
           .antMatchers(tokenKeyPath).access(configurer.getTokenKeyAccess())
           .antMatchers(checkTokenPath).access(configurer.getCheckTokenAccess())

Perhaps configurable through the AuthorizationServerEndpointsConfigurer?

For now my workaround has been to provide my own RestControllers that pass though to the real implementation.

example.

@RestController
public class OAuth2Handler {

    @Autowired
    private TokenEndpoint tokenEndpoint;

    @RequestMapping("/oauth/token")
    public ResponseEntity<OAuth2AccessToken> getAccessToken(Principal principal,
            @RequestParam Map<String, String> parameters) {
        return tokenEndpoint.getAccessToken(principal, parameters);
    }

}
enhancement

Most helpful comment

Can i have one question?

What is the difference between prefix("/api") and pathMapping("/oauth/token","/api/oauth/token") ?
pathMaping is working, prefix looking at the code i have a feeling it should work as the pathMapping just for the whole, but it does not make any effect.

There is no document on that, but this issue is the first in the google search, so it would be helpful, if you can answer here.

All 13 comments

The prefix is not working, not adding anything before the url, so why it's closed

It was closed in 2014 (2.5 years ago) with a commit that shows a change was made and released. I don't think there's anything missing here.

I have expected that if i set a prefix to 'wer', than the whole thing will
be registered under 'wer/oauth'.

@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
...
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {

endpoints.prefix("wer").authenticationManager(authenticationManager);
}
}


org.springframework.boot
spring-boot-starter-parent
1.4.3.RELEASE


org.springframework.security.oauth
spring-security-oauth2

It might be a new bug or misunderstanding of my expectation.

On Wed, Feb 1, 2017 at 5:48 PM, Dave Syer notifications@github.com wrote:

It was closed in 2014 (2.5 years ago) with a commit that shows a change
was made and released. I don't think there's anything missing here.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/spring-projects/spring-security-oauth/issues/214#issuecomment-276711285,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AVsoeO3JRdCCWkN7dYDbM1F-f5bXM5dDks5rYLdngaJpZM4CDXoO
.

Most likely a misunderstanding. If you have a new problem please open a new ticket. If there's a sample we can run to verify the behaviour it will make things a lot smoother.

Can i have one question?

What is the difference between prefix("/api") and pathMapping("/oauth/token","/api/oauth/token") ?
pathMaping is working, prefix looking at the code i have a feeling it should work as the pathMapping just for the whole, but it does not make any effect.

There is no document on that, but this issue is the first in the google search, so it would be helpful, if you can answer here.

@dsyer , would you know the responsibility of method AuthorizationServerEndpointsConfigurer#prefix(String prefix)?
Since it is not to set a prefix for /oauth/authorize, /oauth/check_token, ...

I only get this result as follows:
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.pathMapping("/oauth/authorize", "/api/v1/oauth/authorize")// here
.pathMapping("/oauth/check_token", "/api/v1/oauth/check_token")// here
.pathMapping("/oauth/confirm_access", "/api/v1/oauth/confirm_access")// here
.pathMapping("/oauth/error", "/api/v1/oauth/error")// here
.pathMapping("/oauth/token", "/api/v1/oauth/token")// here
.accessTokenConverter(accessTokenConverter())
.tokenStore(tokenStore())
.authenticationManager(authenticationManager);
}

AFAIK the prefix is intended to be applied to the mappings for all paths. So if it doesn't work, I guess that's a bug, but please read the comments in this issue.

@dsyer
Hello.
I just checked, added to AuthorizationServerEndpointsConfigurer .prefix ("/v1") made no changes.
Please see screenrecord: https://youtu.be/5vqo54RCUfo

Spring Boot 2.0.0.M7, and:

        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
2017-12-03 02:18:21.524  INFO 7269 --- [ost-startStop-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/oauth/authorize]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
2017-12-03 02:18:21.527  INFO 7269 --- [ost-startStop-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/oauth/authorize],methods=[POST],params=[user_oauth_approval]}" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
2017-12-03 02:18:21.532  INFO 7269 --- [ost-startStop-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/oauth/token],methods=[GET]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
2017-12-03 02:18:21.533  INFO 7269 --- [ost-startStop-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/oauth/token],methods=[POST]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
2017-12-03 02:18:21.535  INFO 7269 --- [ost-startStop-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/oauth/check_token]}" onto public java.util.Map<java.lang.String, ?> org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.checkToken(java.lang.String)
2017-12-03 02:18:21.536  INFO 7269 --- [ost-startStop-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/oauth/confirm_access]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
2017-12-03 02:18:21.537  INFO 7269 --- [ost-startStop-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/oauth/error]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint.handleError(javax.servlet.http.HttpServletRequest)

I think "made no changes" is kind of vague (and wrong). The prefix will have been applied to the request matchers in the security filter chain that applies to the /oauth/* endpoints. The log lines you have pasted do not refer to the same feature.

@dsyer
That is, for example, if:

  1. I set .prefix ("/v1") for AuthorizationServerEndpointsConfigurer object
  2. Then in runtime endpoint /v1/oauth/token will be available for requests

Did I understand you correctly?

Did I understand you correctly?

I don't think so, no. the prefix only changes the path matcher in the security filter. Typically you would use it in a Spring Boot app, for example, with server.servlet-path=/v1/. If you only want to change the path to the endpoints you can use the mapping paths individually.

I can verify this is working as intended. We have been using the prefix() method in production for over two years and it still works in the 2.2.1.RELEASE. The prefix() method is needed when an application maps the dispatcher servlet to something other than the default("/"). If the dispatcher servlet is mapped to "/" and you want to change the endpoint paths within the servlet, the pathMapping() method should be used.

Is there a proper way to set the prefix with XML configuration? authorization-server does not have the ability (have not found anything prefix-related in AuthorizationServerBeanDefinitionParser).

<beans
  xmlns:oauth2="http://www.springframework.org/schema/security/oauth2"
  xsi:schemaLocation="
    http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security//spring-security-oauth2.xsd
  "
>
  <oauth2:authorization-server />
</beans>

The only way I can see is to inject FrameworkEndpointHandlerMapping into some helper bean and set the prefix there.

Version in use - latest 2.x (2.3.3.RELEASE)

Was this page helpful?
0 / 5 - 0 ratings