Nous avons une application basée sur oauth2 de sécurité de printemps. Tout fonctionne bien. Mais je ne parviens pas à changer le point de terminaison du jeton par défaut de "/ oauth/token" en "/ external/oauth/token".
My spring-servlet.xml
<http pattern="/external/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
use-expressions="true" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/external/oauth/token" access="isFullyAuthenticated()" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<oauth:authorization-server client-details-service-ref="clientDetails"
token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler" token-endpoint-url="/external/oauth/token">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
Mais le résultat quand j'accède à ce point final est
{
error: "unauthorized"
error_description: "An Authentication object was not found in the SecurityContext"
}
est-ce que je manque quelque chose? Veuillez suggérer.
Avec la version 2.0.5.RELEASE ou supérieure de spring-security-oauth2
Sur une ligne dans Java, testée et fonctionne correctement, elle remplace en quelque sorte la valeur RequestMapping de la classe TokenEndpoint.
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.pathMapping("/oauth/token", "<your custom endpoint>")
}
}
Je me suis juste débattu avec cela pendant quelques jours, mais il fonctionne maintenant sur la dernière version Spring Oauth2 1.0.5.RELEASE. Je ne suis pas sûr à 100% que ma solution est la plus classe (étape 4 en particulier), mais cela fonctionne et je peux aller de l'avant.
Dans mon cas, je voulais supprimer le préfixe /oauth
Des URL pour finir avec seulement /token
Et /authorize
. La solution pour moi était principalement la configuration xml, avec deux hacks pour remplacer les mappages de demande de point de terminaison.
1 - Dans le contexte d'application xml, ajoutez les attributs authorization-endpoint-url
Et token-endpoint-url
À votre élément <oauth:authorization-server>
.
Mien:
<oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" authorization-endpoint-url="/authorize" token-endpoint-url="/token">
2 - Dans le contexte d'application xml, ajustez les points de terminaison de sécurité en conséquence. Il devrait y en avoir deux, qui gèrent respectivement la sécurité sur les URL de jeton et d'authentification. Besoin de mettre à jour le support de modèle sur les balises <http>
Et <intercept-url>
.
Mien:
<http pattern="/token/**" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/token/**" access="IS_AUTHENTICATED_FULLY" />
...
<http pattern="/authorize/**" access-denied-page="/login.jsp?authorization_error=true" disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/authorize/**" access="IS_AUTHENTICATED_FULLY" />
3 - (Si vous avez choisi d'utiliser le filtre clientCreds facultatif.) Dans le contexte d'application xml, vous devriez déjà avoir câblé le bean clientCredentialsTokenEndpointFilter
en tant que <custom-filter> within your
element. So, within the filter's bean, add a
FilterProcessesUrl` propriété.
Mien:
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
<property name="filterProcessesUrl" value="/token" />
</bean>
4 - La dernière étape consiste à remplacer les URL de mappage des demandes des contrôleurs de point de terminaison internes réels. La librairie spring oauth2 est livrée avec deux classes: AuthorizationEndpoint
et TokenEndpoint
. Chacun utilise des annotations de type @RequestMapping
Pour lier l'url (comme nous le faisons tous pour les contrôleurs d'application de nos projets). Pour moi, c'était un effort époustouflant d'essayer de remplacer la valeur des mappages de demandes d'une manière autre que (malheureusement) recréer le package de classe Spring dans mon dossier src, copier les classes AuthorizationEndpoint et TokenEndpoint textuellement dans ce dossier, et modifiez les valeurs d'annotation en ligne @RequestMapping
.
Quoi qu'il en soit, cela fait l'affaire. J'adorerais entendre parler d'une manière plus gracieuse de remplacer les valeurs de mappage de demande de contrôleur de point final.
Merci.
Contexte final de l'application:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:sec="http://www.springframework.org/schema/security" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd
"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<!-- Declare OAuth2 services white-list. (This is the top of the config.) -->
<oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" authorization-endpoint-url="/authorize" token-endpoint-url="/token">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<!-- <oauth:password /> -->
</oauth:authorization-server>
<bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<!-- This bean bridges client auth service and user tokens... kind of an out of place requirement. -->
<property name="tokenServices" ref="tokenServices" />
</bean>
<!-- This starts the far back-end config for client token management. -->
<sec:authentication-manager id="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetailsService" />
</bean>
<bean id="clientDetailsService" class="com.mycompany.oauth.spring.security.oauth2.IntegratedOauth2ClientDetailsService">
<!-- This bean is what wires OAuth2 into the persistence stack for client details stored in the oauth_client table. -->
</bean>
<!-- OAuth is layered on to spring security which is centered around users which requires a user auth manager. -->
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="daoAuthenticationProvider" />
</authentication-manager>
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="clientDetailsService" ref="clientDetailsService" />
</bean>
<bean id="tokenStore" class="com.mycompany.oauth.spring.security.oauth2.IntegratedOAuth2TokenStore">
<!-- This bean is what wires OAuth2 tokens into my company's application stack. -->
<constructor-arg ref="dataSource" />
</bean>
<!-- **************************************************************************************** -->
<!-- Finally, sew OAuth into spring security with some http tags... -->
<!-- **************************************************************************************** -->
<!-- The OAuth2 endpoint for direct token requests (i.e. for client_credentials flow). -->
<http pattern="/token/**" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/token/**" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
<property name="filterProcessesUrl" value="/token" />
</bean>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="myrealm" />
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<!-- The OAuth2 endpoint for user-approved authorization (i.e. for "authorization" flow involving user login/approve). -->
<http pattern="/authorize/**" access-denied-page="/login.jsp?authorization_error=true" disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/authorize/**" access="IS_AUTHENTICATED_FULLY" />
<form-login authentication-failure-url="/login.jsp?authentication_error=true" default-target-url="http://www.mycompany.com/" login-page="/login.jsp" login-processing-url="/login.do" />
<http-basic />
<anonymous />
</http>
</beans>
Pour personnaliser l'URL du point de terminaison du jeton, procédez comme suit.
1) Écrivez votre propre classe qui étend la classe ClientCredentialsTokenEndpointFilter et appelez le constructeur de classe ClientCredentialsTokenEndpointFilter avec la valeur "/ external/oauth/token".
super("/external/oauth/token");
2) Branchez votre nouveau filtre personnalisé dans la configuration de sécurité.
Remplacer
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
avec
<custom-filter ref="your customize filter" after="BASIC_AUTH_FILTER" />
3) Créez votre propre classe pour un nouveau mappage (/ external/oauth/token) et étendez tokenendpoint.
4) Modifiez la valeur d'attribut de modèle de l'élément http & intercept-url en "/ external/oauth/token"
Vous rendez cela plus difficile que ce qu'il devrait être, c'est en fait très simple! (Notez que j'utilise "oauth2:" au lieu de "oauth:" comme balise XML)
Accédez à votre security-context.xml
Recherchez "oauth2: serveur d'autorisation" dans le fichier ci-dessus.
<oauth2:authorization-server
client-details-service-ref="someService"
request-validator-ref="someScopeRequestValidator"
token-services-ref="someTokenServices" >
Ajoutez simplement token-endpoint-url="/oauth/whatever_you_like"
<oauth2:authorization-server
client-details-service-ref="someService"
request-validator-ref="someScopeRequestValidator"
token-services-ref="someTokenServices"
**token-endpoint-url="/oauth/whatever_you_like"** >