Announcement Announcement Module
Collapse
No announcement yet.
auth server without spring mvc Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • auth server without spring mvc

    Looking at sparklr2, I see:

    Code:
    	<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices"
    		user-approval-handler-ref="userApprovalHandler">
    		<oauth:authorization-code />
    		<oauth:implicit />
    		<oauth:refresh-token />
    		<oauth:client-credentials />
    		<oauth:password />
    	</oauth:authorization-server>
            ...
    	<!-- Override the default mappings for approval and error pages -->
    	<bean id="accessConfirmationController" class="org.springframework.security.oauth.examples.sparklr.mvc.AccessConfirmationController">
    		<property name="clientDetailsService" ref="clientDetails" />
    	</bean>
    In my attempt at a custom auth server, I tried replacing the attribute "user-approval-handler-ref" with "user-approval-page" to use my foo.jsp as the approve/deny page. Since this will override the default setting of "forward:/oauth/confirm_access", I also removed the "accessConfirmationController" bean.

    Code:
    	<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" user-approval-page="/foo.jsp">
    		<oauth:authorization-code />
    		<oauth:implicit />
    		<oauth:refresh-token />
    		<oauth:client-credentials />
    		<oauth:password />
    	</oauth:authorization-server>
    But when I try to run/debug, I get "HTTP ERROR: 405, Request method 'GET' not supported".

    1) Why is this the case?
    2) Could you explain (or point me to the proper docs that explain) which classes/paths are involved when a client attempts an auth request to /oauth/authorize?
    3) My breakpoint in AuthorizationEndpoint:authorize does not get triggered, so I'm pretty sure something is misconfigured.

    My environment:
    spring-security-3.1.1.RELEASE
    spring-security-oauth.1.0.0.RC1
    STS 2.9.2.RELEASE
    Windows 7 Enterprise Edition

    web.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    	<filter>
    		<filter-name>springSecurityFilterChain</filter-name>
    		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    		<init-param>
    			<param-name>contextAttribute</param-name>
    			<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value>
    		</init-param>
    	</filter>
    	<filter-mapping>
    		<filter-name>springSecurityFilterChain</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    	<servlet>
    		<servlet-name>spring</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	    <init-param>
    	    	<param-name>contextConfigLocation</param-name>
    	    	<param-value>/WEB-INF/spring-security-context.xml</param-value>
    	    </init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>spring</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    </web-app>
    spring-security-context.xml

    Code:
    <?xml version="1.0" encoding="UTF-8" ?>
    <beans xmlns="http://www.springframework.org/schema/beans" 
    	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	   xmlns:oauth="http://www.springframework.org/schema/security/oauth2" 
    	   xmlns:sec="http://www.springframework.org/schema/security"
    	   xmlns:mvc="http://www.springframework.org/schema/mvc"
    	   xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd 
    	                       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 
    	                       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd 
    	                       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
    	<debug xmlns="http://www.springframework.org/schema/security"/>
    
    	<http pattern="/oauth/token" 
    		  create-session="stateless" 
    		  authentication-manager-ref="clientAuthenticationManager"
    		  entry-point-ref="oauthAuthenticationEntryPoint" 
    		  xmlns="http://www.springframework.org/schema/security">
    
    		<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    		<anonymous enabled="false" />
    		<http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
    		<access-denied-handler ref="oauthAccessDeniedHandler" />
    	</http>
    
    	<http access-denied-page="/login.jsp?authorization_error=true" 
    		  disable-url-rewriting="true" 
    		  xmlns="http://www.springframework.org/schema/security">
    
    		<intercept-url pattern="/oauth/**" access="ROLE_USER" />
    		<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    
    		<form-login authentication-failure-url="/login.jsp?authentication_error=true" 
    					default-target-url="/index.jsp"
    				    login-page="/login.jsp" 
    				    login-processing-url="/login.do" />
    
    		<logout logout-success-url="/index.jsp" logout-url="/logout.do" />
    		<anonymous />
    	</http>
    
    	<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    		<property name="realmName" value="sparklr2" />
    	</bean>
    
    	<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
    
    	<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
    		<authentication-provider user-service-ref="clientDetailsUserService" />
    	</authentication-manager>
    
    	<!-- authentication manager to authenticate resource owners -->
    	<!-- to be replaced by ldap -->
    	<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
    		<authentication-provider>
    			<user-service>
    				<user name="marissa" password="koala" authorities="ROLE_USER" />
    				<user name="paul" password="emu" authorities="ROLE_USER" />
    			</user-service>
    		</authentication-provider>
    	</authentication-manager>
    
    	<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
    		<constructor-arg ref="clientDetails" />
    	</bean>
    
    	<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" user-approval-page="/foo.jsp">
    		<oauth:authorization-code />
    		<oauth:implicit />
    		<oauth:refresh-token />
    		<oauth:client-credentials />
    		<oauth:password />
    	</oauth:authorization-server>
    
    	<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    		<property name="tokenStore" ref="tokenStore" />
    		<property name="supportRefreshToken" value="true" />
    	</bean>
    
    	<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
    
    	<oauth:client-details-service id="clientDetails">
    		<oauth:client client-id="my-trusted-client" 
    		              authorized-grant-types="password,authorization_code,refresh_token,implicit" 
    		              authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT" 
    		              scope="read,write,trust" />
    		<oauth:client client-id="my-trusted-client-with-secret" 
    					  authorized-grant-types="password,authorization_code,refresh_token,implicit"
    					  secret="somesecret" 
    					  authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT" />
    		<oauth:client client-id="my-client-with-secret" 
    		              authorized-grant-types="client_credentials" 
    		              authorities="ROLE_CLIENT" 
    		              scope="read" 
    		              secret="secret" />
    		<oauth:client client-id="my-less-trusted-client" 
    					  authorized-grant-types="authorization_code,implicit"
    					  authorities="ROLE_CLIENT" />
    		<oauth:client client-id="my-less-trusted-autoapprove-client" 
    					  authorized-grant-types="implicit"
    					  authorities="ROLE_CLIENT" />
    		<oauth:client client-id="my-client-with-registered-redirect" 
    					  authorized-grant-types="authorization_code,client_credentials"
    					  authorities="ROLE_CLIENT" 
    					  redirect-uri="http://anywhere?key=value" 
    					  scope="read,trust" />
    		<oauth:client client-id="my-untrusted-client-with-registered-redirect" 
    					  authorized-grant-types="authorization_code"
    					  authorities="ROLE_CLIENT" 
    					  redirect-uri="http://anywhere" 
    					  scope="read" />
    		<oauth:client client-id="tonr" 
    					  resource-ids="sparklr" 
    					  authorized-grant-types="authorization_code,implicit"
    					  authorities="ROLE_CLIENT" 
    					  scope="read,write" 
    					  secret="secret" />
    	</oauth:client-details-service>
    
    </beans>
    Last edited by jrod; Aug 8th, 2012, 11:39 AM. Reason: improperly applied code tags

  • #2
    Does it work with the default user-approval-page (not the same thing as a user-approval-handler)? I don't know if /foo.jsp can be resolved as a view in your config, but I doubt it, so we can narrow down the problem a bit if the default works.

    You didn't really say what your client is doing. Is it sending a GET to /oauth/token perhaps? The method you say your breakpoint was on is mapped to /oauth/authorize by default, as you can see from the annotations on the method, so it seems like your client didn't hit that endpoint?

    Comment


    • #3
      If I'm understanding your request correctly, I activated the "default user-approval-page" by deleting the "user-approval-page" attribute from the "authorization-server" element, like so:

      Code:
      	<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>
      I still get the same error. My "client" right now is an explicit browser GET request to http://localhost/as/oauth/authorize. If unauthenticated, I am redirected to http://localhost/as/login.jsp (as expected) and then redirected back to http://localhost/as/oauth/authorize on success, upon which I get the "HTTP ERROR: 405, Request method 'GET' not supported" error.

      My short-term objective is to get an authorization request using authorization code grant type working without custom Spring MVC components.

      Comment


      • #4
        That's what I meant, and it should work. You didn't say yet what your client is doing precisely. What is the GET you are sending, including all parameters?

        Comment


        • #5
          My GET request is to http://localhost/as/oauth/authorize. No parameters.

          I am aware that response_type and client_id are required parameters per the OAuth2 spec here: http://tools.ietf.org/html/draft-iet...#section-4.1.1, but the 405 error response given does not appear to be correct. It returns an Allow header of POST only. Shouldn't the return response return a 302 with an "invalid_request" error per http://tools.ietf.org/html/draft-iet...ection-4.1.2.1? Shall I file an entry in JIRA for this?

          Btw, if I add "response_type=code", I get a different error: "javax.servlet.ServletException: No adapter for handler [public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpo int.AuthorizationEndpoint.authorize(java.util.Map, java.lang.String,java.util.Map,org.springframework .web.bind.support.SessionStatus,java.security.Prin cipal)]: Does your handler implement a supported interface like Controller"?

          (addendum to my btw: I have figured out why the "No adapter for handler" error was occurring. The solution was to include the <mvc:annotation-driven /> element in my configuration, as sparklr does. As a result, adding the parameter "response_type=code" now returns the spec-compliant "error=invalid_client". Note, however, that the 405 error still occurs for a GET without parameters. As an aside, is there a non-Spring MVC approach to replacing this element?)
          Last edited by jrod; Aug 9th, 2012, 05:11 PM. Reason: added status update

          Comment


          • #6
            OK, it sounds like everything is working. The errors you saw so far look like they are all from Spring mvc when it isn't properly configured - confusing but ultimately understandable (feel free to open JIRA tickets if you think it can be fixed).

            I'm not sure what you mean by "without Spring mvc" though. You mean you want to use the AuthorizationEndpoint and you don't mind using Spring but you don't want to use a DispatcherServlet?
            Last edited by Dave Syer; Aug 10th, 2012, 02:02 AM.

            Comment


            • #7
              OK, I've created SECOAUTH-314 for the 405 issue.

              Btw, user_approval_page="/foo.jsp" did work!

              As for "without Spring MVC", what I mean is: how can/does one use Spring Security OAuth to secure an app not written in Spring MVC? It is my understanding that SS-OAuth requires the DispatcherServlet in order to dispatch requests to SS-OAuth endpoints. That's fine.

              But what about the app-specific controllers? By default, SS-OAuth will map "/oauth/confirm_access" to WhitelabelApprovalEndpoint. Sparklr overrides this mapping with AccessConfirmationController, but this class appears to be written using Spring Web/MVC. How can/does one override this mapping using Struts, plain Java, etc.? The idea is to implement SS-OAuth in upcoming development efforts while leveraging existing knowledge bases, i.e., no experience in Spring MVC.

              Comment


              • #8
                Securing an app with oauth is not really about the framework endpoints - it's a <oauth:resource/> not an <oauth:authorization-server/>. You only need one of the latter?

                If you are happy with foo.jsp then that seems to answer the question about the auth server, right? You just need to set up an approval page, and the auth endpoint doesn't care how it is handled or rendered. Spring will hand off to whatever you tell it to (forward:* is probably the best generic mechanism, but if a jsp works for you, then that's fine).

                Comment


                • #9
                  Ok, after re-reading the last two posts a few times, I realize that I misspoke in my last post. Let me try again.

                  My overall goal is to implement 3 separate components (resource, auth server, client) with SS-OAuth, but this current thread is about the auth server implementation. My reworded question is: how can/does one implement an auth server without using Spring MVC, i.e., how could I reproduce the functionality/role played by sparklr's AccessConfirmationController using Struts/plain old Java/etc.?

                  The foo.jsp comment was a side note. In reality, I do wish to use a controller-based approach, but would like to know how this can be achieved without necessarily using @Controller, <mvc:annotation-driven />, or other aspects of Spring MVC. If this is not easily achievable, that's fine. I just want to be able to explain to non-technical management that in order to use SS-OAuth, we and our vendors MUST learn Spring MVC.

                  Sorry for the confusion.

                  Comment


                  • #10
                    You need <mvc:annotation-driven/> for the framework endpoints. If I were you I would use that for the confirmation controller as well, but if you don't want to I don't see a problem. As your experiment with foo.jsp proved, you can forward or redirect to any endpoint you like (build it with asp.net if you like as long as it posts a form back to the auth endpoint).

                    Comment


                    • #11
                      Ok, I get it. I realize that I'm overthinking this problem. Thanks for your help!

                      Comment

                      Working...
                      X