0

我正在构建一个 grails 应用程序,其中包括:

  1. Spring Security(Spring MVC 项目;不是 Grails 插件)
  2. “OAuth for Spring Security”实现 OAuth2 提供者

为此,我遵循了以下步骤:

  • grails install-templates [见这里]
  • 在 src/templates/war/web.xml 中,添加 Spring Security 过滤器,如下所示:

<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>
  • 在 WEB-INF/applicationContext.xml 文件中定义 Spring Security 和 OAuth beans,包括以下用于处理 /oauth/token

<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 entry-point-ref="clientAuthenticationEntryPoint" />
    <!-- include this only if you need to authenticate clients via request parameters -->     
    <custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
....
....
<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>

问题:我面临的问题是 Spring Security 过滤器正确触发并成功验证了客户端。但在那之后,GrailsDispatcherServlet 无法找到 POST 到 /oauth/token 的处理程序并返回“404 Resource not found”错误。

在调试日志中,我可以看到 /oauth/token 映射到处理程序

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)

我怀疑,这是因为在创建 GrailsDispatcherServlet 和 ApplicationContext 时,Grails 的 DefaultUrlMappingsHolder 在该上下文中创建了一组新的 URL 映射并替换了之前的一组映射。例如,我还在调试日志中看到以下内容


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']] -> /()/provisioning/order/account/()?

这是我向 //oauth/token 发布 HTTP 时的调试日志


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

关于如何使用 Grails Dispatcher“共享”/“传播”这些 Spring /oauth/token 映射的任何想法?

4

1 回答 1

0

当我试图让我的 /oauth/authorize 端点正常工作时,我遇到了类似的症状。为了让事情顺利进行,我必须在 UrlMappings.groovy 中添加以下内容:

    "/oauth/authorize" (uri:"/oauth/authorize.dispatch")
    "/oauth/token" (uri:"/oauth/token.dispatch")

该解决方案来自检查 grails spring-security-oauth 提供程序插件的源代码:

https://github.com/adaptivecomputing/grails-spring-security-oauth2-provider

请注意,让此设置完全工作还可能涉及更新 grails 缓存插件:使用 1.0.1 时,我在映射工作后收到 500(尝试加载 /oauth/authorize 时)。将我的缓存插件升级到 1.1.1 为我解决了这个问题。

希望里面的东西有用。

于 2013-07-09T23:15:30.793 回答