Spring OAuth oauth/token returns 404 war tomcat
Spring OAuth oauth/token returns 404 war on tomcat
我已经按照这里的例子做了 https://www.youtube.com/watch?v=LnJsspvxE1c
在我的 spring war 应用程序上设置 OAuth。
由于我使用的是 spring 4.0.6.RELEASE 和 spring-security-oauth2 2.0.7.RELEASE 我不得不对其进行调整。
HTTP 上/oauth/token returns 404
(因为我的 war 名字是 kma.war 那么请求是 /kma/oauth/token)
根据日志,安全过滤器似乎工作正常。
但是我没有看到对 TokenEndpoint bean 的调用,我什至进行了远程调试并在其上放置了一个断点,但什么也没有。请注意下面日志中的最后一行。
.08:27:06.798 [http-nio-8080-exec-12] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.08:27:06.798 [http-nio-8080-exec-12] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.08:27:06.799 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client-id=kma-client&username=admin@kampyle.com&password=123; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
.08:27:06.799 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client-id=kma-client&username=admin@kampyle.com&password=123; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
.08:27:06.800 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@90550640: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: 10.0.2.2; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
.08:27:06.800 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@90550640: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: 10.0.2.2; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
.08:27:06.803 [http-nio-8080-exec-12] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@270d09d0, returned: 0
.08:27:06.803 [http-nio-8080-exec-12] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@270d09d0, returned: 0
.08:27:06.806 [http-nio-8080-exec-12] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@48ff4ab7, returned: 1
.08:27:06.806 [http-nio-8080-exec-12] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@48ff4ab7, returned: 1
.08:27:06.808 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
.08:27:06.808 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
.08:27:06.809 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
.08:27:06.809 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
.08:27:06.810 [http-nio-8080-exec-12] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client-id=kma-client&username=admin@kampyle.com&password=123 reached end of additional filter chain; proceeding with original chain
.08:27:06.810 [http-nio-8080-exec-12] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client-id=kma-client&username=admin@kampyle.com&password=123 reached end of additional filter chain; proceeding with original chain
.08:27:06.811 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
.08:27:06.811 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
.08:27:06.812 [http-nio-8080-exec-12] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
.08:27:06.812 [http-nio-8080-exec-12] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
我确实在日志的开头看到 url 与 TokenEndpoint Bean 的匹配。
.08:24:05.230 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/confirm_access],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
.08:24:05.230 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/confirm_access],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
.08:24:05.277 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/authorize],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
.08:24:05.277 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/authorize],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
.08:24:05.283 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/authorize],methods=[POST],params=[user_oauth_approval],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
.08:24:05.283 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/authorize],methods=[POST],params=[user_oauth_approval],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
.08:24:05.284 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
.08:24:05.284 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
.08:24:05.292 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
.08:24:05.292 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException****
这是我的 web.xml
<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>KMA Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/kmaAppContext.xml
classpath:/spring/security/kmaSecurityContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<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>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/kmaAppContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
这是我的 kmaAppContext.xml
<beans
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.kma" />
</beans>
最后但同样重要的是,这是我的安全上下文
<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:security="http://www.springframework.org/schema/security"
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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="userDetailsService" class="com.kma.security.UserDetailsService">
</bean>
<security:authentication-manager id="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<!--<security:user-service id="userService">-->
<!--<security:user name="test" password="pass" authorities="customer" />-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<security:http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager">
<security:intercept-url pattern="/oauth/token"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<security:custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="kampyle/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<!-- Authorization Server Configuration of the server is used to provide
implementations of the client details service and token services and to enable
or disable certain aspects of the mechanism globally. -->
<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 authentication-manager-ref="authenticationManager" />
</oauth:authorization-server>
<!-- Client Definition -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="kma-client"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_USER"
redirect-uri="/web"
scope="read,write,trust"
access-token-validity="30"
refresh-token-validity="600"/>
</oauth:client-details-service>
<!-- Token Store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
<!-- VIV -->
<property name="accessTokenValiditySeconds" value="10"/>
</bean>
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!--<security:http create-session="stateless" use-expressions="true">-->
<!--<security:intercept-url pattern="/api/admin/**"-->
<!--access="hasRole('ROLE_ADMIN')" />-->
<!--<security:http-basic />-->
<!--<security:intercept-url pattern="/api/**"-->
<!--access="isAuthenticated()" />-->
<!--<security:http-basic />-->
<!--</security:http>-->
</beans>
您已经加载了两次 XML 文件,并且您点击的安全性 Filter
在其上下文中没有 Servlet
,因此它无法处理该请求。我建议不要使用 web.xml 并切换到 Spring Boot 以使一切正常。如果您不想这样做,请查看旧版本的 sparklr2 示例(例如 1.0.5)并从那里窃取 web.xml。这是:
<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>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/security/kmaSecurityContext.xml
classpath:/spring/kmaAppContext.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
在 Dave 的大量帮助下,我修复了我的 web.xml 和我的安全上下文 xml。我设法到达 oauth/token 端点可用的地步,并且验证了客户端 ID。用户验证仍然失败。
日志显示客户端认证成功
.12:38:10.404 [http-nio-8080-exec-48] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
日志显示用户验证失败:
.12:38:10.439 [http-nio-8080-exec-48] DEBUG o.s.s.w.a.w.BasicAuthenticationFilter - Basic Authentication Authorization header found for user 'admin@kma.com'
.12:38:10.459 [http-nio-8080-exec-48] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
.12:38:10.459 [http-nio-8080-exec-48] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
.12:38:10.460 [http-nio-8080-exec-48] DEBUG o.s.s.a.d.DaoAuthenticationProvider - User 'admin@kma.com' not found
.12:38
这是我更新的 web.xml
<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>KMA Web Application</display-name>
<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.kmaApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>kmaApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/servlet-context.xml
classpath:/spring/kmaAppContext.xml
classpath:/spring/security/kmaSecurityContext.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>kmaApp</servlet-name>
<url-pattern>/api/</url-pattern>
</servlet-mapping>
</web-app>
这是我更新的 kmaSecurityContext.xml
<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:security="http://www.springframework.org/schema/security"
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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="userDetailsService" class="com.kma.security.UserDetailsService">
</bean>
<security:authentication-manager id="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<!--<security:user-service id="userService">-->
<!--<security:user name="test" password="pass" authorities="customer" />-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<security:http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager">
<security:intercept-url pattern="/oauth/token"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<security:custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value=“kma/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager"/>
</bean>
<!-- Authorization Server Configuration of the server is used to provide
implementations of the client details service and token services and to enable
or disable certain aspects of the mechanism globally. -->
<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 authentication-manager-ref="authenticationManager" />
</oauth:authorization-server>
<!-- Client Definition -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="kma-client"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_USER"
redirect-uri="/web"
scope="read,write,trust"
access-token-validity="30"
refresh-token-validity="600"/>
</oauth:client-details-service>
<!-- Token Store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
<!-- VIV -->
<property name="accessTokenValiditySeconds" value="10"/>
</bean>
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!--<security:http create-session="stateless" use-expressions="true">-->
<!--<security:intercept-url pattern="/api/admin/**"-->
<!--access="hasRole('ROLE_ADMIN')" />-->
<!--<security:http-basic />-->
<!--<security:intercept-url pattern="/api/**"-->
<!--access="isAuthenticated()" />-->
<!--<security:http-basic />-->
<!--</security:http>-->
</beans>
这应该不难。我一定是遗漏了一些基本的东西。我仍然得到 404
我的web.xml
<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>KMA Web Application</display-name>
<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.kmaApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>kmaApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--<param-value>-->
<!--classpath:/spring/servlet-context.xml-->
<!--classpath:/spring/kmaAppContext.xml-->
<!--classpath:/spring/security/kmaSecurityContext.xml-->
<!--</param-value>-->
<param-value>
classpath:/spring/kmaAppContext.xml
classpath:/spring/servlet-context.xml
classpath:/spring/security/kmaSecurityContext.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>kmaApp</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
我的 kmaSecurityContext
<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:security="http://www.springframework.org/schema/security"
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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="userDetailsService" class="com.kma.kmawebservice.services.security.MAUserDetailsService">
</bean>
<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<constructor-arg name="strength" value="11"/>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<security:password-encoder ref="encoder"/>
<!--<security:user-service id="userService">-->
<!--<security:user name="test" password="pass" authorities="customer" />-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<security:http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager">
<security:intercept-url pattern="/oauth/token"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<security:custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="kma/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager"/>
</bean>
<!-- Authorization Server Configuration of the server is used to provide
implementations of the client details service and token services and to enable
or disable certain aspects of the mechanism globally. -->
<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 authentication-manager-ref="authenticationManager" />
</oauth:authorization-server>
<!-- Client Definition -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="kma-client"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_USER"
redirect-uri="/web"
scope="read,write,trust"
access-token-validity="30"
refresh-token-validity="600"/>
</oauth:client-details-service>
<!-- Token Store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
<!-- VIV -->
<property name="accessTokenValiditySeconds" value="10"/>
</bean>
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!--<security:http create-session="stateless" use-expressions="true">-->
<!--<security:intercept-url pattern="/api/admin/**"-->
<!--access="hasRole('ROLE_ADMIN')" />-->
<!--<security:http-basic />-->
<!--<security:intercept-url pattern="/api/**"-->
<!--access="isAuthenticated()" />-->
<!--<security:http-basic />-->
<!--</security:http>-->
</beans>
我的servlet-context.xml
<beans
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.kma.kmawebservice.controllers, com.kma.feedback.controllers, com.kma.kmabackend.controllers"/>
<mvc:resources mapping="/**" location="/WEB-INF/" />
</beans>
访问时
我收到 HTTP 状态 404 - /kma/oauth/token
我的 war 名字是 kma.war
日志显示
.20:44:42.375 [http-nio-8080-exec-146] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.20:44:42.375 [http-nio-8080-exec-146] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.20:44:42.376 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
.20:44:42.376 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
.20:44:42.377 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 2 of 8 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
.20:44:42.377 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 2 of 8 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
.20:44:42.378 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 3 of 8 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
.20:44:42.378 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 3 of 8 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
.20:44:42.380 [http-nio-8080-exec-146] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Request is to process authentication
.20:44:42.380 [http-nio-8080-exec-146] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Request is to process authentication
.20:44:42.380 [http-nio-8080-exec-146] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
.20:44:42.380 [http-nio-8080-exec-146] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
.20:44:42.381 [http-nio-8080-exec-146] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
.20:44:42.381 [http-nio-8080-exec-146] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
.20:44:42.382 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 4 of 8 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
.20:44:42.382 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 4 of 8 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
.20:44:42.384 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 5 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
.20:44:42.384 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 5 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
.20:44:42.385 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 6 of 8 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
.20:44:42.385 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 6 of 8 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
.20:44:42.386 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER'
.20:44:42.386 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER'
.20:44:42.388 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
.20:44:42.388 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
.20:44:42.388 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
.20:44:42.388 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
.20:44:42.389 [http-nio-8080-exec-146] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.20:44:42.389 [http-nio-8080-exec-146] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.20:44:42.389 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
.20:44:42.389 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
.20:44:42.390 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
.20:44:42.390 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@2b65b068, returned: 0
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@2b65b068, returned: 0
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@2120921a, returned: 1
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@2120921a, returned: 1
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 reached end of additional filter chain; proceeding with original chain
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 reached end of additional filter chain; proceeding with original chain
.20:44:42.392 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
.20:44:42.392 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
.20:44:42.392 [http-nio-8080-exec-146] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
.20:44:42.392 [http-nio-8080-exec-146] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
我已经按照这里的例子做了 https://www.youtube.com/watch?v=LnJsspvxE1c 在我的 spring war 应用程序上设置 OAuth。 由于我使用的是 spring 4.0.6.RELEASE 和 spring-security-oauth2 2.0.7.RELEASE 我不得不对其进行调整。
HTTP 上/oauth/token returns 404 (因为我的 war 名字是 kma.war 那么请求是 /kma/oauth/token)
根据日志,安全过滤器似乎工作正常。 但是我没有看到对 TokenEndpoint bean 的调用,我什至进行了远程调试并在其上放置了一个断点,但什么也没有。请注意下面日志中的最后一行。
.08:27:06.798 [http-nio-8080-exec-12] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.08:27:06.798 [http-nio-8080-exec-12] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.08:27:06.799 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client-id=kma-client&username=admin@kampyle.com&password=123; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
.08:27:06.799 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client-id=kma-client&username=admin@kampyle.com&password=123; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
.08:27:06.800 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@90550640: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: 10.0.2.2; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
.08:27:06.800 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@90550640: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: 10.0.2.2; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
.08:27:06.803 [http-nio-8080-exec-12] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@270d09d0, returned: 0
.08:27:06.803 [http-nio-8080-exec-12] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@270d09d0, returned: 0
.08:27:06.806 [http-nio-8080-exec-12] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@48ff4ab7, returned: 1
.08:27:06.806 [http-nio-8080-exec-12] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@48ff4ab7, returned: 1
.08:27:06.808 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
.08:27:06.808 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
.08:27:06.809 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
.08:27:06.809 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
.08:27:06.810 [http-nio-8080-exec-12] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client-id=kma-client&username=admin@kampyle.com&password=123 reached end of additional filter chain; proceeding with original chain
.08:27:06.810 [http-nio-8080-exec-12] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client-id=kma-client&username=admin@kampyle.com&password=123 reached end of additional filter chain; proceeding with original chain
.08:27:06.811 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
.08:27:06.811 [http-nio-8080-exec-12] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
.08:27:06.812 [http-nio-8080-exec-12] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
.08:27:06.812 [http-nio-8080-exec-12] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
我确实在日志的开头看到 url 与 TokenEndpoint Bean 的匹配。
.08:24:05.230 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/confirm_access],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
.08:24:05.230 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/confirm_access],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
.08:24:05.277 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/authorize],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
.08:24:05.277 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/authorize],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
.08:24:05.283 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/authorize],methods=[POST],params=[user_oauth_approval],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
.08:24:05.283 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/authorize],methods=[POST],params=[user_oauth_approval],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
.08:24:05.284 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
.08:24:05.284 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
.08:24:05.292 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
.08:24:05.292 [localhost-startStop-2] INFO o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException****
这是我的 web.xml
<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>KMA Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/kmaAppContext.xml
classpath:/spring/security/kmaSecurityContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<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>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/kmaAppContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
这是我的 kmaAppContext.xml
<beans
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.kma" />
</beans>
最后但同样重要的是,这是我的安全上下文
<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:security="http://www.springframework.org/schema/security"
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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="userDetailsService" class="com.kma.security.UserDetailsService">
</bean>
<security:authentication-manager id="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<!--<security:user-service id="userService">-->
<!--<security:user name="test" password="pass" authorities="customer" />-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<security:http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager">
<security:intercept-url pattern="/oauth/token"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<security:custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="kampyle/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<!-- Authorization Server Configuration of the server is used to provide
implementations of the client details service and token services and to enable
or disable certain aspects of the mechanism globally. -->
<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 authentication-manager-ref="authenticationManager" />
</oauth:authorization-server>
<!-- Client Definition -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="kma-client"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_USER"
redirect-uri="/web"
scope="read,write,trust"
access-token-validity="30"
refresh-token-validity="600"/>
</oauth:client-details-service>
<!-- Token Store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
<!-- VIV -->
<property name="accessTokenValiditySeconds" value="10"/>
</bean>
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!--<security:http create-session="stateless" use-expressions="true">-->
<!--<security:intercept-url pattern="/api/admin/**"-->
<!--access="hasRole('ROLE_ADMIN')" />-->
<!--<security:http-basic />-->
<!--<security:intercept-url pattern="/api/**"-->
<!--access="isAuthenticated()" />-->
<!--<security:http-basic />-->
<!--</security:http>-->
</beans>
您已经加载了两次 XML 文件,并且您点击的安全性 Filter
在其上下文中没有 Servlet
,因此它无法处理该请求。我建议不要使用 web.xml 并切换到 Spring Boot 以使一切正常。如果您不想这样做,请查看旧版本的 sparklr2 示例(例如 1.0.5)并从那里窃取 web.xml。这是:
<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>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/security/kmaSecurityContext.xml
classpath:/spring/kmaAppContext.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
在 Dave 的大量帮助下,我修复了我的 web.xml 和我的安全上下文 xml。我设法到达 oauth/token 端点可用的地步,并且验证了客户端 ID。用户验证仍然失败。
日志显示客户端认证成功
.12:38:10.404 [http-nio-8080-exec-48] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
日志显示用户验证失败:
.12:38:10.439 [http-nio-8080-exec-48] DEBUG o.s.s.w.a.w.BasicAuthenticationFilter - Basic Authentication Authorization header found for user 'admin@kma.com'
.12:38:10.459 [http-nio-8080-exec-48] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
.12:38:10.459 [http-nio-8080-exec-48] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
.12:38:10.460 [http-nio-8080-exec-48] DEBUG o.s.s.a.d.DaoAuthenticationProvider - User 'admin@kma.com' not found
.12:38
这是我更新的 web.xml
<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>KMA Web Application</display-name>
<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.kmaApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>kmaApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/servlet-context.xml
classpath:/spring/kmaAppContext.xml
classpath:/spring/security/kmaSecurityContext.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>kmaApp</servlet-name>
<url-pattern>/api/</url-pattern>
</servlet-mapping>
</web-app>
这是我更新的 kmaSecurityContext.xml
<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:security="http://www.springframework.org/schema/security"
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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="userDetailsService" class="com.kma.security.UserDetailsService">
</bean>
<security:authentication-manager id="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<!--<security:user-service id="userService">-->
<!--<security:user name="test" password="pass" authorities="customer" />-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<security:http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager">
<security:intercept-url pattern="/oauth/token"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<security:custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value=“kma/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager"/>
</bean>
<!-- Authorization Server Configuration of the server is used to provide
implementations of the client details service and token services and to enable
or disable certain aspects of the mechanism globally. -->
<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 authentication-manager-ref="authenticationManager" />
</oauth:authorization-server>
<!-- Client Definition -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="kma-client"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_USER"
redirect-uri="/web"
scope="read,write,trust"
access-token-validity="30"
refresh-token-validity="600"/>
</oauth:client-details-service>
<!-- Token Store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
<!-- VIV -->
<property name="accessTokenValiditySeconds" value="10"/>
</bean>
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!--<security:http create-session="stateless" use-expressions="true">-->
<!--<security:intercept-url pattern="/api/admin/**"-->
<!--access="hasRole('ROLE_ADMIN')" />-->
<!--<security:http-basic />-->
<!--<security:intercept-url pattern="/api/**"-->
<!--access="isAuthenticated()" />-->
<!--<security:http-basic />-->
<!--</security:http>-->
</beans>
这应该不难。我一定是遗漏了一些基本的东西。我仍然得到 404
我的web.xml
<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>KMA Web Application</display-name>
<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.kmaApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>kmaApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--<param-value>-->
<!--classpath:/spring/servlet-context.xml-->
<!--classpath:/spring/kmaAppContext.xml-->
<!--classpath:/spring/security/kmaSecurityContext.xml-->
<!--</param-value>-->
<param-value>
classpath:/spring/kmaAppContext.xml
classpath:/spring/servlet-context.xml
classpath:/spring/security/kmaSecurityContext.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>kmaApp</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
我的 kmaSecurityContext
<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:security="http://www.springframework.org/schema/security"
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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="userDetailsService" class="com.kma.kmawebservice.services.security.MAUserDetailsService">
</bean>
<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<constructor-arg name="strength" value="11"/>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<security:password-encoder ref="encoder"/>
<!--<security:user-service id="userService">-->
<!--<security:user name="test" password="pass" authorities="customer" />-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<security:http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager">
<security:intercept-url pattern="/oauth/token"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<security:custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="kma/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager"/>
</bean>
<!-- Authorization Server Configuration of the server is used to provide
implementations of the client details service and token services and to enable
or disable certain aspects of the mechanism globally. -->
<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 authentication-manager-ref="authenticationManager" />
</oauth:authorization-server>
<!-- Client Definition -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="kma-client"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_USER"
redirect-uri="/web"
scope="read,write,trust"
access-token-validity="30"
refresh-token-validity="600"/>
</oauth:client-details-service>
<!-- Token Store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
<!-- VIV -->
<property name="accessTokenValiditySeconds" value="10"/>
</bean>
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!--<security:http create-session="stateless" use-expressions="true">-->
<!--<security:intercept-url pattern="/api/admin/**"-->
<!--access="hasRole('ROLE_ADMIN')" />-->
<!--<security:http-basic />-->
<!--<security:intercept-url pattern="/api/**"-->
<!--access="isAuthenticated()" />-->
<!--<security:http-basic />-->
<!--</security:http>-->
</beans>
我的servlet-context.xml
<beans
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.kma.kmawebservice.controllers, com.kma.feedback.controllers, com.kma.kmabackend.controllers"/>
<mvc:resources mapping="/**" location="/WEB-INF/" />
</beans>
访问时
我收到 HTTP 状态 404 - /kma/oauth/token 我的 war 名字是 kma.war
日志显示
.20:44:42.375 [http-nio-8080-exec-146] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.20:44:42.375 [http-nio-8080-exec-146] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.20:44:42.376 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
.20:44:42.376 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
.20:44:42.377 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 2 of 8 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
.20:44:42.377 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 2 of 8 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
.20:44:42.378 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 3 of 8 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
.20:44:42.378 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 3 of 8 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
.20:44:42.380 [http-nio-8080-exec-146] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Request is to process authentication
.20:44:42.380 [http-nio-8080-exec-146] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Request is to process authentication
.20:44:42.380 [http-nio-8080-exec-146] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
.20:44:42.380 [http-nio-8080-exec-146] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
.20:44:42.381 [http-nio-8080-exec-146] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
.20:44:42.381 [http-nio-8080-exec-146] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
.20:44:42.382 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 4 of 8 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
.20:44:42.382 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 4 of 8 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
.20:44:42.384 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 5 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
.20:44:42.384 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 5 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
.20:44:42.385 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 6 of 8 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
.20:44:42.385 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 6 of 8 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
.20:44:42.386 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER'
.20:44:42.386 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER'
.20:44:42.388 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
.20:44:42.388 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
.20:44:42.388 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
.20:44:42.388 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
.20:44:42.389 [http-nio-8080-exec-146] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.20:44:42.389 [http-nio-8080-exec-146] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
.20:44:42.389 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
.20:44:42.389 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
.20:44:42.390 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
.20:44:42.390 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7afe829: Principal: org.springframework.security.core.userdetails.User@93b2ea19: Username: kma-client; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@2b65b068, returned: 0
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@2b65b068, returned: 0
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@2120921a, returned: 1
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@2120921a, returned: 1
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 reached end of additional filter chain; proceeding with original chain
.20:44:42.391 [http-nio-8080-exec-146] DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123 reached end of additional filter chain; proceeding with original chain
.20:44:42.392 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
.20:44:42.392 [http-nio-8080-exec-146] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
.20:44:42.392 [http-nio-8080-exec-146] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
.20:44:42.392 [http-nio-8080-exec-146] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed