Announcement Announcement Module
Collapse
No announcement yet.
How to implement 2-legged OAuth to authenticate client requests? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to implement 2-legged OAuth to authenticate client requests?

    Hi,
    I want to add security to a simple Jersey+spring application.
    On provider (server) side, i want to use spring Oauth security to protect a given URL and i have a jersey client(consumer + user) to send requests.

    I have this error message :

    Code:
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.security.filterChains' is defined
    Those are my configuration files :

    web.xml :
    Code:
    <web-app id="WebApp_ID" version="2.4"
    	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    	<display-name>Restful Web Application</display-name>
    		  <filter>
    		    <filter-name>springSecurityFilterChain</filter-name>
    		    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    		</filter>
    		
    		<filter-mapping>
    		    <filter-name>springSecurityFilterChain</filter-name>
    		    <url-pattern>/*</url-pattern>
    		</filter-mapping>
    		        
            <!-- context param -->
            
            <context-param>
    	        <param-name>contextConfigLocation</param-name>
    			<param-value>
    				/WEB-INF/applicationContext.xml
    				/WEB-INF/service-securityContext.xml
    				
    			 </param-value>
           </context-param>
            <!-- Listeners -->
            <listener>
                <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
            </listener>
            <listener>
                <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
             </listener>
            <listener>
                <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
            </listener>
        
            <!-- Servlet -->
    		<servlet>
    			<servlet-name>jersey-serlvet</servlet-name>
    			<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    			<init-param>
    				<param-name>com.sun.jersey.config.property.packages</param-name>
    				<param-value>com.perso.rest</param-value>
    			</init-param>
    			<load-on-startup>1</load-on-startup>
    		</servlet>
    
    		<servlet-mapping>
    			<servlet-name>jersey-serlvet</servlet-name>
    			<url-pattern>/rest/*</url-pattern>
    		</servlet-mapping>
    	 
    
    </web-app>
    applicationContext.xml (in /WEB-INF/) :
    Code:
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="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">
     
    	<context:component-scan base-package="com.perso.rest" />
    	     <context:annotation-config/>
    	
       
    </beans>
    and the service-securityContext.xml file , (in /WEB-INF/) :
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:oauth="http://www.springframework.org/schema/security/oauth"
                 xmlns:beans="http://www.springframework.org/schema/beans"
                 xmlns:context="http://www.springframework.org/schema/context"
                 xsi:schemaLocation="
    				http://www.springframework.org/schema/beans
    				http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    				http://www.springframework.org/schema/security/oauth
    				http://www.springframework.org/schema/security/spring-security-oauth.xsd
    				http://www.springframework.org/schema/security
    				http://www.springframework.org/schema/security/spring-security-3.1.xsd">
    				
    				
    				
    <beans:bean name="myConsumerDetailsService" class="com.perso.security.oauth.myConsumerDetailsServiceImpl"/>
     
      <beans:bean name="oauthProcessingFilterEntryPoint" class="org.springframework.security.oauth.provider.OAuthProcessingFilterEntryPoint" />
     
      <http auto-config="true" entry-point-ref="oauthProcessingFilterEntryPoint">
        <intercept-url pattern="/rest/**" access="ROLE_OAUTH_USER"/>
        <intercept-url pattern="/oauth/**" access="ROLE_OAUTH_USER" />
        <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
      </http>
      
     <authentication-manager>
        <authentication-provider user-service-ref="myConsumerDetailsService"/>
     </authentication-manager>
     
      <oauth:provider consumer-details-service-ref="myConsumerDetailsService"
                      token-services-ref="tokenServices"
                      require10a="true"/>
                      
                
     
      <oauth:token-services id="tokenServices"/>
    </beans:beans>
    Am using spring security 3.1.0.RC1, and oauth version 1.0.0.M4. The myConsumerDetailsServiceImpl class specifies consumer key and secret to access the provider resource(which is a simple POJO).

    Where am i wrong in my configuration?

    Thx

  • #2
    Can you share your implementation of ConsumerDetailsService. If loadConsumerByKey returns any object of type ConsumerDetails with the correct GrantedAuthoritys in them and with isRequiredToObtainAuthenticatedToken() returning false, I think the config you have should work fine. Also, the user-service-ref doesn't have to be the ConsumerDetailsService. That can be a normal UserDetailsService returning UserDetails. I don't that is used in the OAuth flow.
    Last edited by subhashish; Nov 3rd, 2011, 10:32 AM.

    Comment


    • #3
      Hi this is the implementation of ConsumerDetailsService. It is based on an example given on another topic.
      Code:
      public class myConsumerDetailsServiceImpl implements ConsumerDetailsService,UserDetailsService{
      
      	private static final Log log = LogFactory.getLog( myConsumerDetailsServiceImpl.class );
      	 
      	 private Map<String, ConsumerDetails> consumers;
      	 
      	 public myConsumerDetailsServiceImpl(){
      		 consumers.put("consumer-key1", createConsumerDetails("consumer-key1", "consumer-name1", "consumer-secret1"));
      		
      	 }
      	@Override
      	public UserDetails loadUserByUsername(String arg0)
      			throws UsernameNotFoundException, DataAccessException {
      		 throw new UnsupportedOperationException();
      	}
      
      	@Override
      	public ConsumerDetails loadConsumerByConsumerKey(String key)throws OAuthException {
      		 log.info( "Request received to find consumer for consumerKey=[" + key + "]" );
      		 
      	        ConsumerDetails consumer = consumers.get( key );
      	        if ( consumer == null ) {
      	            log.info( "Result: No consumer found for [" + key + "]"  );
      	            throw new OAuthException( "No consumer found for key " + key );
      	        }
      	        if ( log.isDebugEnabled() ) {
      	            log.debug( "Result: Found consumer [" + consumer.getConsumerName() + "]" );
      	        }
      	        return consumer;
      		
      	}
      	private ConsumerDetails createConsumerDetails( String consumerKey, String consumerName, String consumerSecret ) {
              log.info("Creation of Consumer : "+ consumerKey);
      		SharedConsumerSecret secret = new SharedConsumerSecret( consumerSecret );
       
              BaseConsumerDetails bcd = new BaseConsumerDetails();
              bcd.setConsumerKey( consumerKey );
              bcd.setConsumerName( consumerName );
              bcd.setSignatureSecret( secret );
              List<GrantedAuthority> grantedAuthoryties = new ArrayList<GrantedAuthority>();
              grantedAuthoryties.add(new GrantedAuthorityImpl( "ROLE_OAUTH_USER" ));
              bcd.setAuthorities( grantedAuthoryties );
       
             
              bcd.setRequiredToObtainAuthenticatedToken( false );
              
       
              return bcd;
          }
      
      }
      Now i am having another disturbing error message :

      Code:
      Failed to convert property value of type 'org.springframework.security.oauth.provider.InMemoryConsumerDetailsService' to required type 'org.springframework.security.core.userdetails.UserDetailsService' for property 'userDetailsService'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.oauth.provider.InMemoryConsumerDetailsService] to required type [org.springframework.security.core.userdetails.UserDetailsService] for property 'userDetailsService'
      Any suggestion?

      Comment


      • #4
        You know what, I got the same problem with 1.0.0.M4. Looks like there's some issues in the <oauthrovider> bean's dependencies.

        Comment


        • #5
          And how did you fix it?

          Comment


          • #6
            Haven't been able to fix it yet. Just came across the problem today itself. Looks like a problem with 1.0.0.M4. I am going to try with other milestone versions. Btw, if it's alright with you to use spring secuity 2.0.4 (I know its going back but it works), you can try this dependency instead of 1.0.0.M4.
            <dependency>
            <groupId>org.codehaus.spring-security-oauth</groupId>
            <artifactId>spring-security-oauth</artifactId>
            <version>3.9</version>
            </dependency>

            The sparklr example I have uses that and it works alright.

            Comment


            • #7
              This is the more specific Error message i got :
              Code:
              Failed to convert property value of type 'org.springframework.security.oauth.provider.InMemoryConsumerDetailsService' to required type 'org.springframework.security.core.userdetails.UserDetailsService' for property 'userDetailsService'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.oauth.provider.InMemoryConsumerDetailsService] to required type [org.springframework.security.core.userdetails.UserDetailsService] for property 'userDetailsService': no matching editors or conversion strategy found
              Any help would be appreciate...
              Thx

              Comment


              • #8
                To go back to the original exception that you had, I resolved that by upgrading spring security to 3.1.0.RC3 (the latest). The resolved the NoSuchBeanDefinitionException. Can't think of why the next exception is coming up though. If you aren't using <oauth:consumer-details-service> I don't think this should come up at all. Which bean's loading causes this one?

                Comment


                • #9
                  Hummm am using the same version of spring security (3.1.0.RC3) and didnt specify <oauth:consumer-details-service> :
                  This is my config in POM.xml :
                  Code:
                    <properties>
                          <spring.version>3.0.6.RELEASE</spring.version>
                          <spring.security.version>3.1.0.RC3</spring.security.version>
                          <spring.security.oauth.version>1.0.0.M4</spring.security.oauth.version>
                      </properties>
                  Can you please send me a zip of your working example project?

                  Comment


                  • #10
                    Here's the config that's working for me. Let me know if it helps.

                    <sec:http auto-config="false" pattern="/services/**" use-expressions="true" entry-point-ref="oAuthProcessingFilterEntryPoint">
                    <sec:intercept-url pattern="/services/**" access="isAuthenticated()"/>
                    </sec:http>

                    <sec:authentication-manager alias="authenticationManager">
                    <sec:authentication-provider user-service-ref="userDetailsService">
                    <secassword-encoder hash="md5"/>
                    </sec:authentication-provider>
                    </sec:authentication-manager>

                    <bean id="userDetailsService"
                    class="my.custom.UserDetailsService"/>

                    <bean id="oAuthAuthenticationHandler" class="my.custom.OAuthAuthenticationHandler" /> <!-- Just returns the authentication object for now-->

                    <bean id="oAuthProcessingFilterEntryPoint" class="org.springframework.security.oauth.provider .OAuthProcessingFilterEntryPoint" />

                    <oauthrovider consumer-details-service-ref="consumerDetailsService"
                    auth-handler-ref="oAuthAuthenticationHandler"
                    token-services-ref="tokenServices"
                    require10a="false"/>

                    <oauth:token-services id="tokenServices"/>

                    <bean id="consumerDetailsService"
                    class="my.custom.ConsumerDetailsService" /> <!-- Implements loadConsumerByKey-->

                    Comment


                    • #11
                      Hi,
                      Which spring, spring security and oauth versions are you using ?

                      Comment


                      • #12
                        Spring 3.0.5.RELEASE
                        Spring security - 3.0.1.RC1
                        Spring security oauth - 1.0.0.M4

                        Comment


                        • #13
                          HUmm i have the same error message as previously. Could you please send me a zip of you project so that i can check where i am wrong?
                          Thx

                          Comment


                          • #14
                            Unfortunately can't do that as I am working in office. I'll try cooking up a sample tomorrow and send that across.

                            Comment


                            • #15
                              Hi Have u done that sample 2-legged oauth project? Let me know pls.
                              Thanks.

                              Comment

                              Working...
                              X