2014-03-06 3 views
21

Wir haben eine auf Sicherheit basierende oauth2-basierte Anwendung. Alles funktioniert gut. Aber ich konnte den Standard-Token-Endpunkt nicht von "/ oauth/token" auf "/ external/oauth/token" ändern.Wie ändere ich den Standard-Token-Endpoint von outh2?

Meine feder 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> 

Aber das Ergebnis, wenn ich Zugriff auf diese Endpunkt ist

{ 
    error: "unauthorized" 
    error_description: "An Authentication object was not found in the SecurityContext" 
} 

bin ich irgend etwas fehlt? Bitte vorschlagen.

Antwort

3

Führen Sie die folgenden Schritte aus, um die Token-Endpunkt-URL anzupassen.

1) Schreiben Sie Ihre eigene Klasse, die ClientCredentialsTokenEndpointFilter-Klasse & erweitert, rufen Sie den ClientCredentialsTokenEndpointFilter-Klassenkonstruktor mit dem Wert "/ external/oauth/token" auf.

super("/external/oauth/token"); 

2) Schließen Sie Ihren neuen Anpassungsfilter in der Sicherheitskonfiguration an.

ersetzen

<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" /> 

mit

<custom-filter ref="your customize filter" after="BASIC_AUTH_FILTER" /> 

3) Erstellen Sie Ihre eigene Klasse für neue Zuordnung (/ extern/oauth/Token) & erweitern tokenendpoint.

4) Änderung http & Intercept-URL-Muster des Elements Attributwert auf „/ extern/oauth/token“

+0

Hallo Anurag, ich habe alle diese Zeile hinzugefügt und meine Endzeigerreferenz auf -Tag gegeben. Beim Start des Servers wird jedoch eine Exception ausgelöst: "java.lang.IllegalArgumentException: authenticationManager muss angegeben werden". Irgendetwas anderes muss hier getan werden? .. Danke – Srikanth

+0

müssen Sie AuthenticationManager Bean in Ihrem clientCredentialsTokenEndpoint Filter – Imrank

6

Nur mit dieser für ein paar Tage zu kämpfen, aber es hat arbeitet jetzt an neuesten Frühling OAuth2 1.0.5 .FREISETZUNG. Ich bin nicht 100% sicher, dass meine Lösung die Klasse ist (Schritt 4 im Besonderen), aber es funktioniert und ich kann weitermachen.

In meinem Fall wollte ich das /oauth Präfix von den URLs entfernen, um nur mit /token und /authorize enden. Die Lösung für mich war hauptsächlich xml config, mit zwei Hacks, um die Anforderungszuordnungen zu überschreiben.

1 - Fügen Sie in App context xml authorization-endpoint-url und token-endpoint-url Ihrem Element <oauth:authorization-server> hinzu.

Mine:

<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 - In App Kontext xml, entsprechend der Sicherheitsendpunkte einzustellen. Es sollte zwei geben, die jeweils die Sicherheit auf dem Token und den Authentifizierungen verwalten. Müssen die Musterstütze auf <http> und <intercept-url> Tags aktualisieren.

Mine:

<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 - (Wenn Sie die optionalen clientCreds Filter verwenden gewählt haben.) In App Kontext xml, sollten Sie bereits verdrahtet in haben die clientCredentialsTokenEndpointFilter Bohne als <custom-filter> within yourelement. So, within the filter's bean, add a filterProcessesUrl` Eigenschaft.

Mine:

<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter"> 
    <property name="authenticationManager" ref="clientAuthenticationManager" /> 
    <property name="filterProcessesUrl" value="/token" /> 
</bean> 

4 - Der letzte Schritt ist die Anforderungszuordnung URLs der tatsächlichen internen Endpunkt-Controller zu überschreiben. Der Frühling oauth2 Lib kommt mit zwei Klassen: AuthorizationEndpoint und TokenEndpoint. Jeder verwendet @RequestMapping Typ Anmerkungen, um die URL zu binden (wie wir alle für die App-Controller unserer Projekte tun). Für mich war es eine haarsträubende Bemühung, den Wert der Anforderungszuordnungen auf irgendeine andere Weise außer dem (leider) neu zu erstellen, das Spring-Klassenpaket in meinem src-Ordner zu kopieren, die AuthorizationEndpoint- und TokenEndpoint-Klassen wörtlich in diesen Ordner zu kopieren. und bearbeiten Sie die Inline-@RequestMapping Annotationswerte.

Wie auch immer, das macht den Trick. Ich würde mich freuen, wenn Sie eine etwas elegantere Möglichkeit zum Überschreiben der Anforderungszuordnungswerte für Endpoint Controller hören könnten.

Danke.

Finale, Arbeits app Kontext:

<?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> 
+0

setzen, bitte schlagen Sie mir vor, was 'realmName' in' clientAuthenticationEntryPoint' ist. Ich habe auch den gleichen Fehler, aber nicht die Standard-Token-URL anpassen. Ich benutze einen Spring-Rest-Service mit für Oauth. –

4

Sie machen diese härter als das, was es sein sollte, ist es eigentlich ganz einfach! (Man beachte ich verwende "oauth2:" anstelle von "oauth:" als XML-Tag)

  1. Gehen Sie zu Ihrer Sicherheit context.xml

  2. Suche "oauth2: Berechtigungs-server" in der obigen Datei.

    <oauth2:authorization-server 
           client-details-service-ref="someService" 
           request-validator-ref="someScopeRequestValidator" 
           token-services-ref="someTokenServices" > 
    
  3. Fügen Sie einfach 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"** > 
    
+0

Ich versuche, die URL des Token-Endpunktes zu ändern, wie Sie zu '/ api/v1/oauth/token' gesagt haben, aber es gibt Fehler: 'Ein Authentifizierungsobjekt wurde im SecurityContext nicht gefunden'. Fehle ich etwas? – Anita

+0

Diese Lösung half mir benutzerdefinierte OAuth2RequestValidator in TokenEndpoint über XML Config injizieren. – Raf

25

Mit der Version 2.0.5.RELEASE oder oberhalb der federsicherheits oauth2

In einer Zeile in Java-basierte Konfiguration getestet und funktioniert gut, irgendwie überschreibt es den RequestMapping-Wert der TokenEndpoint-Klasse.

@Configuration 
@EnableAuthorizationServer 
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {  

     @Override 
     public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
      endpoints 
       .pathMapping("/oauth/token", "<your custom endpoint>") 
     } 
} 
+0

Hi @Emilien Brigand Ich habe das versucht, um die Endpunkte zu ändern. PathMapping ("/ oauth/authorize", "/ external/oauth/authorize"); aber es geht nicht zu meiner benutzerdefinierten Aktionszuordnung, die im benutzerdefinierten Controller definiert ist. Können Sie bitte eine Lösung vorschlagen? –

+0

nur für den Fall, haben Sie den Pfad Ihres Endpunkts anstelle von "/ external/oauth/authorize"? –

+0

Hallo @Emilien Brigand danke für deine Antwort. Können Sie mir bitte sagen, über welchen Pfad des Endpunkts Sie sprechen? –

Verwandte Themen