Spring security oauth 2 simple example

29,422

You 2nd XML that you pasted here is the spring's XML for the oauth-provider and the protected-resource, which in your case run in the same webapp. (you can separate them, of course, if you wish).

The client (the 1st pasted-XML) is a different story. If I understand you correctly, you want your client to run without Spring's help (to be a regular webapp, and not spring-security-oauth-client webapp).

You have to understand how oAuth works: the client tries to get to a protected resource; if it does not have the access-token, it is being redirected to the oAuth-provider (that shows the login page and supplies the token). By the standard, the request for the access-token MUST contain a "redirect-uri" param, so after a successful login, the oAuth-provider knows where to redirect the client to. The oAuth client does it for you, and if you delete the "oauth client" from your web.xml, you now have to implement this by yourself.

Thanks for your answer. But I still don't understand how spring security influences my oAuth client. And can I use for client side spring-oauth (spring-mvc) without spring-security?

When you write this line in your XML:

< oauth:client id="oauth2ClientFilter" />

it means that you use spring-security-oauth, which is a package dedicated for oauth, built on spring-security. If you dig in, it puts a special filter (OAuth2ClientContextFilter) in the chain that handles the oAuth stuff, that are relevant for the client. One of them is sending the request with all the params ("redirect-uri" is one of them).

If you decide NOT to use spring-security-oauth, well - you will have to implement this logic by yourself...

Hope that helps!

Share:
29,422
chaldaean
Author by

chaldaean

Updated on July 23, 2020

Comments

  • chaldaean
    chaldaean almost 4 years

    I try to implement my own example based on official tutorial Sparklr2/Tonr2. Everything looks good but when I remove from web.xml in my Tonr2 implementation, spring security filter I have exception:

    No redirect URI has been established for the current request

    I can't understand what URL should I use. Here is my code, for client implementation:

    <!--apply the oauth client context -->
    <oauth:client id="oauth2ClientFilter" />
    
    <!--define an oauth 2 resource for sparklr -->
    <oauth:resource id="provider" type="authorization_code" client-id="client" client-secret="secret" 
        access-token-uri="http://localhost:8080/provider/oauth/token" user-authorization-uri="http://localhost:8080/provider/oauth/authorize" scope="read,write" />
    
    <beans:bean id="clientController" class="com.aouth.client.ClientController">
        <beans:property name="trustedClientRestTemplate">
            <oauth:rest-template resource="provider" />
        </beans:property>
    </beans:bean>
    

    And for provider:

    <http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
        <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
        <anonymous enabled="false" />
        <http-basic />
    </http>
    
    <authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
        <authentication-provider user-service-ref="clientDetailsUserService" />
    </authentication-manager>
    
    <bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
        <constructor-arg ref="clientDetails" />
    </bean>
    
    <!-- The OAuth2 protected resources are separated out into their own block so we can deal with authorization and error handling 
        separately. This isn't mandatory, but it makes it easier to control the behaviour. -->
    <http pattern="/secured" create-session="never" access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/secured" access="ROLE_USER,SCOPE_READ" />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <http-basic />
    </http>
    
    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
        <constructor-arg>
            <list>
                <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
                <bean class="org.springframework.security.access.vote.RoleVoter" />
                <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
            </list>
        </constructor-arg>
    </bean>
    
    <oauth:resource-server id="resourceServerFilter" resource-id="resource" token-services-ref="tokenServices" />
    
    <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="clientDetails"/>
    </bean>
    
    <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
    
    <http auto-config="true" xmlns="http://www.springframework.org/schema/security">
        <intercept-url pattern="/test" access="ROLE_USER" />
        <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    </http>
    
    <authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
        <authentication-provider>
            <user-service>
                <user name="pr" password="pr" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
    
    <oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" >
        <oauth:authorization-code />
        <oauth:implicit />
        <oauth:refresh-token />
        <oauth:client-credentials />
        <oauth:password />
    </oauth:authorization-server>
    
    <oauth:client-details-service id="clientDetails">
        <oauth:client client-id="client" resource-ids="resource" authorized-grant-types="authorization_code, implicit"
            authorities="ROLE_CLIENT" scope="read,write" secret="secret" />
    </oauth:client-details-service>
    

    I just want my client to work without spring security. And when I need my protected resource I want to login only on provider side.

  • chaldaean
    chaldaean over 11 years
    Thanks for your answer. But I still don't understand how spring security influent on my oAuth client. And can I use for client side spring-oauth (spring-mvc) without spring-security?
  • chaldaean
    chaldaean over 11 years
    Thanks OhadR, your answer indeed helped me to understand.
  • PRASANTHMV
    PRASANTHMV over 9 years
    @chaldaean can you please demonstrate the full security.xml file after correcting it
  • Dejell
    Dejell about 9 years
    Thanks @OhadR. so if I understand correctly, if I only want to use it for retrieving token for making future calls to the app, it's not possible? I don't need redirect uri
  • Dejell
    Dejell about 9 years
    I see many examples that use the spring security just to retrieve a token. My client side is angular.js and my server side is REST api. Also Twitter API works with a token
  • Dejell
    Dejell about 9 years
    jaxenter.com/rest-api-spring-java-8-112289.html this tutorial seems to be doing so - just calling to retrieve the token and than making calls with it
  • OhadR
    OhadR about 9 years
    first of all, you can leave the "redirect-uri" empty if you do not really need it; besides, before the token you get the code, right? note that in your case, you should not work in "Authorization Code" Authorization Grant, but in other one "implicit", see 1.3. in the example you sent here, they use "client-credentials". in this type of usage you really don't need the redirect-uri )