【问题标题】:Spring OAuth oauth/token returns 404 war on tomcatSpring OAuth oauth/token 在 tomcat 上返回 404 战争
【发布时间】:2015-05-28 21:05:09
【问题描述】:

我已经按照这里的例子https://www.youtube.com/watch?v=LnJsspvxE1c 在我的春季战争应用程序上设置 OAuth。 由于我使用的是 spring 4.0.6.RELEASE 和 spring-security-oauth2 2.0.7.RELEASE 我不得不对其进行调整。

HTTP Get on /oauth/token 返回 404 (因为我的战争名称是 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>

【问题讨论】:

    标签: java spring http oauth spring-security-oauth2


    【解决方案1】:

    这不应该那么难。我一定缺少一些基本的东西。我仍然得到 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://localhost:8080/kma/oauth/token?grant_type=password&client_id=kma-client&username=admin@kma.com&password=123

    我得到 HTTP 状态 404 - /kma/oauth/token 我的战争名称是 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 
    

    【讨论】:

    • 作为说明,我还尝试将 servlet 映射模式更改为 /*
    • servlet 映射必须与安全配置相匹配。映射到 /* 时的日志是否不同?
    • 添加日志作为新答案
    【解决方案2】:

    在 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>
    

    【讨论】:

    • 我尝试将 更改为使用别名而不是 id。 。这似乎适用于用户身份验证。但我又回到了原点。 404.跨度>
    • 这是我现在在日志中看到的内容:FilterSecurityInterceptor - 先前已验证:UsernamePasswordAuthenticationToken@d7afe829:主体:User@93b2ea19:用户名:kma-client;密码保护];启用:真; AccountNonExpired:真;凭据非过期:真; AccountNonLocked:真;授予权限:ROLE_USER;凭证:[受保护];已认证:真实;详细信息:空;授予权限:ROLE_USER AffirmativeBased - 投票者:org.springframework.security.access.vote.RoleVoter@10e504fc,返回:0 FilterSecurityInterceptor - 授权成功
    • Servlet 只映射到一个路径(/api/)。当然,您需要一个模式(如果您想为 tojen 端点提供服务,建议使用 /*)。
    • 那么你的servlet路径是什么?在 Spring Security 中与您的令牌端点匹配的模式是什么?他们必须排队记得吗?
    【解决方案3】:

    您已经加载了两次 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>
    

    【讨论】:

    • 嗨,戴夫。你怎么知道我加载了 xml 两次?哪个xml?我现在需要继续使用 web.xml。您粘贴的 web.xml 的主要区别是什么?
    • 这两个文件:classpath:/spring/kmaAppContext.xml,classpath:/spring/security/kmaSecurityContext.xml 被加载了两次(一次在 servlet 中,一次在上下文加载侦听器中)。
    • 我现在需要继续使用 web.xml。您粘贴的 web.xml 的主要区别是什么?
    • 我应该将上下文 xmls 保留在上下文加载器中并将其从 servlet 中删除吗?如果我这样做了,我会收到一个错误,它找不到 appServletContext.xml,这就是我在那里添加它的原因。
    • 我的 web.xml 中有一条评论。我用 XML 的显式路径替换了它。
    猜你喜欢
    • 2018-04-26
    • 2016-01-30
    • 2015-11-10
    • 2018-11-03
    • 1970-01-01
    • 2012-11-04
    • 2016-08-25
    • 2016-09-06
    • 2016-11-25
    相关资源
    最近更新 更多