Note that there are some explanatory texts on larger screens.

plurals
  1. POUrl Mapping fails for /oauth/token - Spring security + OAuth in a Grails application
    primarykey
    data
    text
    <p>I am building a grails application that includes: </p> <ol> <li>Spring Security (Spring MVC project; NOT the Grails plugin) </li> <li>"OAuth for Spring Security" to implement an OAuth2 provider</li> </ol> <p>To accomplish this, I followed the following steps: </p> <ul> <li>grails install-templates <a href="http://grails.org/doc/2.2.1/ref/Command%20Line/install-templates.html" rel="nofollow"> [see here]</a> </li> <li>in src/templates/war/web.xml, add the Spring Security filter as below: </li> </ul> <pre><code> &lt;filter&gt; &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt; &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt; &lt;/filter-mapping&gt; </code></pre> <ul> <li>define Spring Security and OAuth beans in WEB-INF/applicationContext.xml file including the following for handling /oauth/token</li> </ul> <pre><code> &lt;http pattern=&quot;/oauth/token&quot; create-session=&quot;stateless&quot; authentication-manager-ref=&quot;clientAuthenticationManager&quot; xmlns=&quot;http://www.springframework.org/schema/security&quot;&gt; &lt;intercept-url pattern=&quot;/oauth/token&quot; access=&quot;IS_AUTHENTICATED_FULLY&quot; /&gt; &lt;anonymous enabled=&quot;false&quot; /&gt; &lt;http-basic entry-point-ref=&quot;clientAuthenticationEntryPoint&quot; /&gt; &lt;!-- include this only if you need to authenticate clients via request parameters --&gt; &lt;custom-filter ref=&quot;clientCredentialsTokenEndpointFilter&quot; after=&quot;BASIC_AUTH_FILTER&quot; /&gt; &lt;access-denied-handler ref=&quot;oauthAccessDeniedHandler&quot; /&gt; &lt;/http&gt; .... .... &lt;oauth:authorization-server client-details-service-ref=&quot;clientDetails&quot; token-services-ref=&quot;tokenServices&quot;&gt; &lt;oauth:authorization-code /&gt; &lt;oauth:implicit /&gt; &lt;oauth:refresh-token /&gt; &lt;oauth:client-credentials /&gt; &lt;oauth:password /&gt; &lt;/oauth:authorization-server&gt; </code></pre> <p><b>Issue:</b> The issue that I am facing is that Spring Security filters fire correctly and successfully authenticate the client. <b>But after that, the GrailsDispatcherServlet is unable to find a handler for the POST to /oauth/token and returns a "404 Resource not found" error.</b></p> <p>In the debug log, I can see that /oauth/token is mapped to a handler </p> <pre><code>2013-06-17 19:21:04,469 [localhost-startStop-1] INFO endpoint.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.lang.String,java.util.Map) </code></pre> <p>I suspect, this happens because when GrailsDispatcherServlet and ApplicationContext is created, the Grails' DefaultUrlMappingsHolder creates a new set of URL mappings in that context and replaces the previous set of mappings. For e.g., I also see the following in my debug log </p> <p><pre><code> 2013-06-17 19:31:01,339 [localhost-startStop-1] DEBUG mapping.DefaultUrlMappingsHolder - Reverse mapping: [DefaultUrlMappingsHolder.UrlMappingKey@250f9a46 controller = 'account', action = [null], plugin = [null], params = set['API_VERSION']] -> /(<em>)/provisioning/order/account/(</em>)? </pre></code></p> <p>Here's the debug log for when I make an HTTP post to //oauth/token</p> <pre><code> 2013-06-17 19:31:05,798 [http-bio-8080-exec-1] DEBUG util.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token' 2013-06-17 19:31:05,804 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 1 of 5 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 2013-06-17 19:31:05,805 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 2 of 5 in additional filter chain; firing Filter: 'BasicAuthenticationFilter' 2013-06-17 19:31:05,807 [http-bio-8080-exec-1] DEBUG www.BasicAuthenticationFilter - Basic Authentication Authorization header found for user 'j2' 2013-06-17 19:31:05,808 [http-bio-8080-exec-1] DEBUG authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider 2013-06-17 19:31:05,813 [http-bio-8080-exec-1] DEBUG www.BasicAuthenticationFilter - Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ffff9a33: Principal: org.springframework.security.core.userdetails.User@d08: Username: j2; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ALL; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ALL 2013-06-17 19:31:05,813 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 3 of 5 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 2013-06-17 19:31:05,814 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 4 of 5 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 2013-06-17 19:31:05,814 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 5 of 5 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 2013-06-17 19:31:05,814 [http-bio-8080-exec-1] DEBUG util.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token' 2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token; Attributes: [IS_AUTHENTICATED_FULLY] 2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ffff9a33: Principal: org.springframework.security.core.userdetails.User@d08: Username: j2; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ALL; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ALL 2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@35f3198f, returned: 0 2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@6b1316f4, returned: 1 2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG intercept.FilterSecurityInterceptor - Authorization successful 2013-06-17 19:31:05,816 [http-bio-8080-exec-1] DEBUG intercept.FilterSecurityInterceptor - RunAsManager did not change Authentication object 2013-06-17 19:31:05,816 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token reached end of additional filter chain; proceeding with original chain 2013-06-17 19:31:05,826 [http-bio-8080-exec-1] DEBUG mvc.GrailsWebRequestFilter - Bound Grails request context to thread: SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.connector.RequestFacade@519cea9e]] 2013-06-17 19:31:05,846 [http-bio-8080-exec-1] DEBUG filter.UrlMappingsFilter - Executing URL mapping filter... 2013-06-17 19:31:05,847 [http-bio-8080-exec-1] DEBUG filter.UrlMappingsFilter - URL Mappings ------------ / /(*)/provisioning/order/account/(*)? /(*)/provisioning/order/demographics/(*)? /(*)/provisioning/inventory/phone_numbers/(*)? /(*)/billing/regions/(*)? /(*)/billing/countries/(*)? /(*)/provisioning/credit_cards/(*)? /(*)/provisioning/states/(*)? /(*)/provisioning/countries/(*)? /(*)/provisioning/phone_cities/(*)? /(*)/general/languages/(*)? /(*)/docs/constraints/(*)? 2013-06-17 19:31:05,847 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/] 2013-06-17 19:31:05,847 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/order/account/(*)?] 2013-06-17 19:31:05,847 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/order/demographics/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/inventory/phone_numbers/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/billing/regions/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/billing/countries/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/credit_cards/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/states/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/countries/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/phone_cities/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/general/languages/(*)?] 2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/docs/constraints/(*)?] 2013-06-17 19:31:05,857 [http-bio-8080-exec-1] DEBUG filter.UrlMappingsFilter - No match found, processing remaining filter chain. 2013-06-17 19:31:05,860 [http-bio-8080-exec-1] DEBUG mvc.GrailsWebRequestFilter - Cleared Grails thread-bound request context: SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.connector.RequestFacade@519cea9e]] 2013-06-17 19:31:05,860 [http-bio-8080-exec-1] DEBUG access.ExceptionTranslationFilter - Chain processed normally 2013-06-17 19:31:05,860 [http-bio-8080-exec-1] DEBUG context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed </code></pre> <p>Any ideas on how to "share"/"propagate" those Spring /oauth/token mappings with the Grails Dispatcher?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload