Spring Security Oauth 2 custom token end point url
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-
Adding
token-endpoint-url
inauthorization-server
definitionChange at
<http pattern="changed URL"
Change at
<intercept-url pattern="changed URL"
And, adding
filterProcessesUrl
property withvalue="changed url"
inClientCredentialsTokenEndpointFilter
.
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 ?
Anita
Updated on June 16, 2022Comments
-
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
inoauth:authorization-server
also adding custom filter class that will overrideClientCredentialsTokenEndpointFilter
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 almost 9 yearsToo 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 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.