Announcement Announcement Module
Collapse
No announcement yet.
Problem in the new design for OAuth2 endpoints Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem in the new design for OAuth2 endpoints

    Hi,

    I have integrated the new version of spring security oauth with my app where the the authorization and token endpoints - are implemented as @Controller beans with @RequestMapping. Everything works fine as expected.
    The problem I am encountering is that the AuthenticationManager instance in TokenEndpoint class is null when when the request URI /oauth/token is called.
    During the start of the server I observe that this instance is set by dependency injection but when /oauth/token/ POST request is called from theclient side to request for an access token I find authenticationManager to be null which throws a NullPointerException.
    Could you let me know If I am missing something?
    Also when I update the latest jar from the maven repository I do not find the XSD changes getting updated. Everything else gets updated.

    Thanks,
    Sweta

  • #2
    That sounds odd (obviously it works for me, and in the sample apps and tests). Did you somehow define two instances of the TokenEndpoint in your server? I'm not even sure how you could have done that. Can you share your configuration?

    The XSD should be in the JAR file when you build or download it right (the snapshot build is still broken, I think, so to get a new jar you have to build it your self for now)? It should definitely work at runtime. If you mean that your XML editor is not picking up the changes, then it's the editor, not the XSD that is wrong. The version on the internet is probably old, so your editor might be picking that one up. If you raise a JIRA ticket to remind me I can copy it over later.

    Comment


    • #3
      Hi Dave,

      I do not see any possibility of creating two instances of TokenEndpoint as I have observed it while debugging my code.
      Below is my security configuration:

      Code:
       
         <http access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">
          
          <intercept-url pattern="/photos.web" access="ROLE_USERS,SCOPE_READ" />
          <intercept-url pattern="/photos.web/**" access="ROLE_USERS,SCOPE_READ" />
          <intercept-url pattern="/trusted/**" access="ROLE_USERS,SCOPE_TRUST" />
          <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_ANONYMOUSLY" />
           <intercept-url pattern="/oauth/**" access="ROLE_USERS" />
          <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY,DENY_OAUTH" />
          
          <access-denied-handler ref="accessDeniedHandler"/>
         <form-login default-target-url="/busiLogin.web" authentication-failure-url="/error.jsp" login-page="/index.jsp"/>
          <remember-me/>
          <custom-filter ref="oauth2ProviderFilter" after="EXCEPTION_TRANSLATION_FILTER" />
         </http>
         
         <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
      		<property name="decisionVoters">
      			<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>
      		</property>
      	</bean>
      
         
      <bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
      	
         <authentication-manager xmlns="http://www.springframework.org/schema/security">
      	   <authentication-provider>
      	    <password-encoder ref="passwordEncoder"/>
      		<jdbc-user-service data-source-ref="dataSource"
       
      		   users-by-username-query="
      		      select user_name,password,login_valid
      		      from users where user_name=?" 
       
      		   authorities-by-username-query="
      		      select u.user_name, concat('ROLE_', upper(replace(trim(bp.name), ' ', '_'))) from users u, permissions bp
      		      where u.user_id = bp.user_id and u.user_name =?  " 
       
       
      		/>
      	   </authentication-provider>
      	</authentication-manager>
             
          <bean id="tokenServices" class="com.services.JdbcCustOAuth2ProviderTokenServices">
                     <constructor-arg><ref bean="dataSource"/></constructor-arg>        
             </bean> 
      	
      	<oauth:provider id="oauth2ProviderFilter" client-details-service-ref="appConsumerDetailsService" token-services-ref="tokenServices">
      			<oauth:authorization-code/>
      	</oauth:provider>
      	
      		
      	<bean id="appConsumerDetailsService" class="com.services.AppConsumerDetailsService">
      		<constructor-arg><ref bean="sessionFactory"/></constructor-arg>	
      	</bean>
      
      	<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
      		<!--you could also wire in the expression handler up at the layer of the http filters. See https://jira.springsource.org/browse/SEC-1452 -->
      		<sec:expression-handler ref="oauthExpressionHandler" />
      	</sec:global-method-security>
      
      	<oauth:expression-handler id="oauthExpressionHandler" />
      	
      	<bean id="accessConfirmationController" class="com.annotations.AccessConfirmationController">
      		<property name="clientDetailsService" ref="appConsumerDetailsService" />
      	</bean>
      We have used Controllers with and without annotations in out project so we have specified the following in our application context
      Code:
      <context:component-scan base-package="org.springframework.security.oauth2.provider.endpoint" />
      <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
      <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
      <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
      and the following url patterns in web.xml
      Code:
      <servlet-mapping>
      	    <servlet-name>SpringAction</servlet-name>
      	    <url-pattern>*.web</url-pattern>
      	    <url-pattern>/oauth/authorize</url-pattern>
      	    <url-pattern>/oauth/confirm_access</url-pattern>
      	    <url-pattern>/oauth/token</url-pattern>
      </servlet-mapping>
      Thanks,
      Sweta

      Comment


      • #4
        OK, I see the problem, then. You have <oauth:\provider/> and a component scan on the oauth2 base package. Remove the component scan, or modify it if you need it for something else, and it should work.

        Comment


        • #5
          Thanks Dave. Everything works fine now..

          Comment


          • #6
            Hey,

            I have same problem, but if I remove component scan the endpoint "/oauth/token" is not detected

            Code:
            <context:component-scan base-package="com.mypackages, org.springframework.security.oauth2.provider.endpoint" use-default-filters="true"/>
            Thanks,

            Comment


            • #7
              The <oauth:\provider/> element has to be in the servlet application context - see the sparklr2 sample for one example of how to do that. Maybe you put it in the root (parent) context, which used to work because the implementation was by filters? I'll update the docs.

              Comment


              • #8
                Yes, as Dave said the <oauth:\provider/> element has to be in the servlet application context.
                Additionally I faced that problem because we used different URL patterns in our web.xml. I solved that issue by declaring the following in my servlet application context and web.xml:
                In servlet application context (i.e spring-security.xml)
                <mvc:default-servlet-handler />
                In web.xml include the following url pattern:
                <url-pattern>/</url-pattern>
                as is already given in sparklr2 sample.

                Comment


                • #9
                  thanks Dave and Sweta,

                  I have moved <oauth:\provider/> to the servlet application context and everything is fine....

                  Usually, I separate my application contexts in terms of application layers/technology,

                  /src/main/resources/META-INF/spring/applicationContext-security-oauth-provider.xml
                  /src/main/resources/META-INF/spring/applicationContext-security.xml
                  /src/main/resources/META-INF/spring/applicationContext-data.xml
                  /src/main/resources/META-INF/spring/applicationContext.xml
                  etc

                  and
                  /src/main/webapp/WEB-INF/spring/webmvc-config.xml

                  Comment


                  • #10
                    I ran into the same issue, and while moving the provider into my webmvc servlet context file resolved the issue, i still had to define it in my security.xml file as well. If i removed it from my security.xml file the filter wasn't able to find the oauth2ProviderFilter as the servlet context had initialized yet. Maybe this is a defect, or an enhancement but i was curious if i was doing something incorrectly as I really don't want to define these beans twice, once only for the controller to be parsed properly by mvc.

                    Comment


                    • #11
                      Hmm. I'll have to think about that one. The problem is that traditionally people put their security configuration in the parent context and their servlet handlers in the child servlet context. I think that might have been a misfeature of the old Acegi Security, and it's not really necessary for a Spring MVC application. The OAuth2 endpoints are clearly servlet handlers, but the way they are designed currently they rely on a filter (just for exception handling I think - the wrong way to do it), which lives in the main security filter chain. Assuming you have a Spring MVC application, one way to fix it in the short term is to consolidate your configuration (like in the samples). You actually don't need any of the <oauth:authorization-server/> stuff in your parent context, and you don't need any of the <oauth:resource-srever/> in your servlet context, so that's another way to reduce the duplication. Longer term we can try and accommodate the split better in the oauth namespace.

                      Thanks for the feedback. This is really useful.

                      Comment

                      Working...
                      X