java - Spring OAuth oauth/token 在 tomcat 上返回 404 war

标签 java spring http oauth spring-security-oauth2

我按照这里的例子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 返回 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>

关于java - Spring OAuth oauth/token 在 tomcat 上返回 404 war,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29251510/

相关文章:

javascript - 如何正确向Controller发送参数? ( thymeleaf +Javascript)

安卓注释 : @Rest annotation compile error

java - 需要帮助从 Spring mvc 中的列表对象迭代列表

java - 如何避免使用 Spring-Boot 下载嵌入式 MongoDb

java - 如何在我的 Java 项目中实现 UnityJDBC?

http - curl 转换为简单的 http 请求?

php - post 形式的数据顺序是否与 web 形式的数据顺序相同?

web-services - 使用 HTTP 状态代码时区分基础结构和业务逻辑

java - 发送的对象与接收的对象不同

java - 匿名类是否总是保持对其封闭实例的引用?