Spring Security Oauth 2 custom token end point url

12,866

Solution 1

Finally got it working. One thing that was missing in this question was <beans:property name="filterProcessesUrl" value="/api/v1/token" /> in ClientCredentialsTokenEndpointFilter Bean definition.

In the custom-filter tag there is reference of ClientCredentialsTokenEndpointFilter Bean and in that Bean one property is defined that id filterProcessesUrl and the value is given as the desired url,as in my case it is /api/v1/token. And this solves the problem.

So basically for changing token-endpoint-url,we need to change at 4 place-

  1. Adding token-endpoint-url in authorization-server definition

  2. Change at <http pattern="changed URL"

  3. Change at <intercept-url pattern="changed URL"

  4. And, adding filterProcessesUrl property with value="changed url" in ClientCredentialsTokenEndpointFilter .

Solution 2

Isn't the path "/oauth/token" kind of a defacto standard ?

Unfortunately I don't have the exact answer for XML configuration but maybe this Java config can give you hints.

When you extend AuthorizationServerConfigurerAdapter the following method gives you access to a Builder giving access to authorization server configuration :

@Override
public void configure(AuthorizationServerEndpointsConfigurer oauthServer) throws Exception {
    oauthServer

        // Here you can override the default endpoints mappings
        .pathMapping("/oauth/authorize", "/api/v1/authorize")
        .pathMapping("/oauth/token", "/api/v1/token")

        // .. rest of the authorization server customization
        .authenticationManager(authenticationManager)
        .tokenStore(tokenStore);
}

It is kind of weird because you override the mappings through a Map, you have to know each path you want to override, and there is not really any hint or documentation in the AuthorizationServerEndpointsConfigurer class.

In the end it works, as when the authorization server starts the logs show :

...
.s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/api/v1/authorize],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto ...
.s.o.p.e.FrameworkEndpointHandlerMapping : Mapped "{[/api/v1/token],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto ...

...

I guess in XML it should translate to some element inside <oauth:authorization-server> like :

<oauth:authorization-server>
  <!-- ... -->
  <pathMappings>
    <!-- key/value here -->
  </pathMappings>
</oauth:authorization-server>

EDIT : After checking the XML schema, you probably had it right at first, as the token-endpoint-url element should have done the math according to the comments :

        <xs:attribute name="token-endpoint-url" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    The URL at which a request for an access token
                    will be serviced.
                    Default value: "/oauth/token"
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

Maybe you should file an issue in the spring-security-oauth issue tracker ?

Share:
12,866
Anita
Author by

Anita

Updated on June 16, 2022

Comments

  • Anita
    Anita almost 2 years

    Hello I have to integrate spring security oauth2 in my project. So I added the configuration related part and its working fine. But the problem is that the first request for token goes to "/oauth/token" and I want to change it to "api/v1/token" . I searched for that and find some solution like adding token-endpoint-url in oauth:authorization-server also adding custom filter class that will override ClientCredentialsTokenEndpointFilter and passing the url to constructor. But these didn't worked . I am getting following error for request to "api/v1/token"-

    An Authentication object was not found in the SecurityContext

    My configuration is mainly xml based . Spring-security.xml file-

    <http pattern="/api/v1/token" create-session="stateless"
          authentication-manager-ref="authenticationManager"
          xmlns="http://www.springframework.org/schema/security" > 
        <intercept-url pattern="/api/v1/token" access="IS_AUTHENTICATED_FULLY" />
        <anonymous enabled="false" />
        <http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
        <custom-filter ref="customClientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /> 
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>
    <http pattern="/test/**" create-session="never"
          entry-point-ref="oauthAuthenticationEntryPoint"       
          xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/test/**" access="ROLE_USER" />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>
    <beans:bean id="oauthAuthenticationEntryPoint"
                class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    </beans:bean>
     <beans:bean id="oauthAccessDeniedHandler"
        class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
    </beans:bean>
    <beans:bean id="clientAuthenticationEntryPoint"
                class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
        <beans:property name="realmName" value="springsec/client" />
        <beans:property name="typeName" value="Basic" />
    </beans:bean>
    
    
     <beans:bean id="customClientCredentialsTokenEndpointFilter"
                class="com.walletdoc.oauth.web.security.CustomClientCredentialsTokenEndpointFilter">
         <beans:property name="authenticationManager" ref="authenticationManager" />
    </beans:bean>
    
    <authentication-manager alias="authenticationManager"
                            xmlns="http://www.springframework.org/schema/security">
        <authentication-provider user-service-ref="clientDetailsUserService" />
    </authentication-manager>
    <beans:bean id="clientDetails" class="com.walletdoc.oauth.web.security.SpringSecurityClientService">
        <beans:property name="id" value="mysupplycompany" />
        <beans:property name="secretKey" value="mycompanykey" />
        <beans:property name="authorities" value="ROLE_CLIENT" />
    </beans:bean>
    <beans:bean id="clientDetailsUserService"
                class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
        <beans:constructor-arg ref="clientDetails"/>
    </beans:bean>
    
    
    
    <authentication-manager id="userAuthenticationManager" 
                            xmlns="http://www.springframework.org/schema/security">
        <authentication-provider  ref="customUserAuthenticationProvider">
        </authentication-provider>
    </authentication-manager>
    
    <beans:bean id="customUserAuthenticationProvider"
                class="com.walletdoc.oauth.web.security.ClientAuthenticationProvider">
    </beans:bean>
    
    <oauth:authorization-server
        client-details-service-ref="clientDetails" token-services-ref="tokenServices" token-endpoint-url="/api/v1/token">
        <oauth:authorization-code />
        <oauth:implicit/>
        <oauth:refresh-token/>
        <oauth:client-credentials />
        <oauth:password authentication-manager-ref="userAuthenticationManager" />
    </oauth:authorization-server>
    
    <oauth:resource-server id="resourceServerFilter"
                           resource-id="springsec" token-services-ref="tokenServices" />
    
    <beans:bean id="tokenStore"
                class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
    
    <beans:bean id="tokenServices"
                class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
        <beans:property name="tokenStore" ref="tokenStore" />
        <beans:property name="supportRefreshToken" value="true" />
        <beans:property name="accessTokenValiditySeconds" value="3600"></beans:property>
        <beans:property name="clientDetailsService" ref="clientDetails" />
    </beans:bean>
    

    I have been trying to solve this issue from last 2 days ,so any help will be appreciated.

  • Michael Técourt
    Michael Técourt almost 9 years
    Too bad, you should probably file the issue on Spring's issue tracker. In the meanwhile, maybe you can use Java @Configuration instead of XML since it works. Good luck :)
  • Steve
    Steve over 6 years
    "Isn't the path "/oauth/token" kind of a defacto standard ?" According to the spec, the endpoints are not prefixed with /oauth. They are simply /authorize and /token. So it's probably not a bad idea to change these in the Spring config.