0

我当前的 Spring MVC 应用程序最初设计为仅适用于经过身份验证的用户,因此使用应用程序用户将导航到www.myappdomain.com. 但是现在我想将这些资源迁移到下www.myappdomain.com/member,并将以前的资源用作静态网站(或任何人都可以访问)。

我能想到的一种解决方案是修改所有控制器,RequestMapping("member")但这也需要我修改 JSP 中的所有映射。

有没有其他更方便的方式来实现我想要的?

更新

根据 M. Deinum 给出的答案,我决定创建额外的 servlet 名称。但是,每次我尝试登录(使用或不使用正确的凭据)时,我都会被重定向到登录页面。

web.xml

<servlet>
        <servlet-name>site</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>site</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/member/*</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter>
        <filter-name>HttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/member/*</url-pattern>
    </filter-mapping>

安全上下文.xml

<http pattern="/**/favicon.ico" security="none" />
    <http pattern="/**/resources/**" security="none" />
    <http pattern="/maintenance.html" security="none" />

    <http auto-config="false" use-expressions="true"
        disable-url-rewriting="true">
        <intercept-url pattern="/member/login*" access="permitAll"
            requires-channel="https" />
        <form-login authentication-success-handler-ref="myAuthenticationSuccessHandler"
            login-page="/member/login" authentication-failure-url="/member/loginFailed" />
        <intercept-url pattern="/member/**" access="isFullyAuthenticated()"
            requires-channel="https" />
        <session-management
            session-authentication-error-url="/member/loginFailed">
            <concurrency-control error-if-maximum-exceeded="true"
                max-sessions="1" />
        </session-management>
        <logout invalidate-session="true" delete-cookies="JSESSIONID" />
    </http>

登录.jsp

<form method="POST" action="<c:url value='j_spring_security_check'/>"
            autocomplete="off">
            <fieldset>
                <label for="username"><spring:message code="label.username" />
                    <span class="ico"><img src="${imgPath}/user.png"
                        alt="Username Icon" border="0"></span></label> <input type="text"
                    name="j_username" id="username" required autofocus> <label
                    for="password"><spring:message code="label.password" /> <span
                    class="ico"><img src="${imgPath}/pass.png"
                        alt="Password Icon" border="0"></span></label> <input type="password"
                    name="j_password" id="password" required>
            </fieldset>
            <c:if test="${!empty errorMsg}">
                <div class="errorMessage">
                    ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}</div>
            </c:if>
            <fieldset>
                <button type="submit">
                    &gt;&gt;&nbsp;&nbsp;&nbsp;
                    <spring:message code="label.go" />
                </button>
            </fieldset>
        </form>

一旦我按下登录表单中的提交按钮,就会生成调试跟踪。

org.springframework.web

DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'app' processing GET request for [/dnag2/member/login]
DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /login
DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Returning handler method [public java.lang.String com.dnag2.controller.AuthenticationController.initLogin(org.springframework.ui.ModelMap,javax.servlet.http.HttpServletRequest)]
DEBUG: org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/dnag2/member/login] is: -1
DEBUG: org.springframework.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'login'; URL [/WEB-INF/views/login.jsp]] in DispatcherServlet with name 'app'
DEBUG: org.springframework.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/views/login.jsp] in InternalResourceView 'login'
DEBUG: org.springframework.web.servlet.DispatcherServlet - Successfully completed request

org.springframework.security

DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/member/j_spring_security_check'; against '/**/favicon.ico'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/member/j_spring_security_check'; against '/**/resources/**'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/member/j_spring_security_check'; against '/maintenance.html'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 1 of 11 in additional filter chain; firing Filter: 'ChannelProcessingFilter'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/member/j_spring_security_check'; against '/member/login*'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/member/j_spring_security_check'; against '/member/**'
DEBUG: org.springframework.security.web.access.channel.ChannelProcessingFilter - Request: FilterInvocation: URL: /member/j_spring_security_check; ConfigAttributes: [REQUIRES_SECURE_CHANNEL]
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@2d4d3ce6. A new one will be created.
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 3 of 11 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
DEBUG: org.springframework.security.web.authentication.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: FACD6A03C058DB14AFEE4FF7BAF6A1FA; Granted Authorities: ROLE_ANONYMOUS'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /member/j_spring_security_check at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/member/j_spring_security_check'; against '/member/login*'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/member/j_spring_security_check'; against '/member/**'
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /member/j_spring_security_check; Attributes: [isFullyAuthenticated()]
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: FACD6A03C058DB14AFEE4FF7BAF6A1FA; Granted Authorities: ROLE_ANONYMOUS
DEBUG: org.springframework.security.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@72ffa2f5, returned: -1
DEBUG: org.springframework.security.web.access.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:144)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
4

3 回答 3

1

如果一切都在一场战争中,并且您不想修改控制器,只需将另一个控制器添加DispatcherServlet到您的 web.xml 中。

<servlet>
    <servlet-name>member</servlet-name>
    // Other properties
</servlet>

<servlet-mapping>    
    <servlet-name>member</servlet-name>
    <url-pattern>/member/*</url-pattern>
</servlet-mapping>

此 servlet 包含/加载所有动态控制器,您当前的 servlet 将提供和处理所有静态内容。您可能需要稍微调整一下配置。

当使用多个DispatcherServlet实例并且 Spring Security 仅映射到其中一个时(在本例中为 /member/*),请记住<form-login .. />正确配置元素。您需要添加该属性login-processing-url,以便它正确匹配登录 url。默认情况下是'/

<form-login login-processing-url="/member/j_spring_security_check" ... />

使其在过滤器映射中工作。

于 2013-09-13T08:49:52.160 回答
0

您需要将第二个更改intercept-url为仅包含成员路径。像这样。

<intercept-url pattern="/members/**" access="isFullyAuthenticated()" requires-channel="https" />

更新

由于这通常很容易在 Spring 中实现,因此我采用了您的安全上下文并对其进行了简化。试试这个。一旦它工作,您可以添加一些额外的选项:

<http pattern="/**/favicon.ico" security="none" />
<http pattern="/**/resources/**" security="none" />
<http pattern="/maintenance.html" security="none" />
<http pattern="/member/login**" security="none" />

<http pattern="/member/**" auto-config="false" use-expressions="true">

    <intercept-url pattern="/member/**" access="isAuthenticated()"
        requires-channel="https" />

    <form-login 
       authentication-success-handler-ref="myAuthenticationSuccessHandler"
       login-page="/member/login" 
       authentication-failure-url="/member/loginFailed" 
    />

    <logout invalidate-session="true" delete-cookies="JSESSIONID" />
</http>
于 2013-09-18T02:12:39.883 回答
0

采用 <sec:http pattern="/member " security="none" />

于 2013-09-18T05:17:05.050 回答