我是Spring Security的新手,所以我制作了一个小型的webapp,以便尝试并找到一个对我正在处理的项目有用的配置。 我强迫我的登录页面通过HTTPS访问,我需要在登录后切换回HTTP。换句话说:
我尝试了几种方法但是我不能像上面所说的那样使它工作。 我读了Spring Security FAQ,我发现没有“自然”的方式做我想做的事,但我被要求这样做,因此我需要一个我自己找不到的解决方法。
我正在使用Spring Security 3.1.0。 我的Web容器是Tomcat 6.0.33。
这是我的Spring Security配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:sec="http://www.springframework.org/schema/security"
xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<sec:http auto-config="true" use-expressions="true">
<sec:intercept-url pattern="/log*.htm" access="anonymous"
requires-channel="https" />
<sec:intercept-url pattern="/admin/**" access="hasRole('admin')"
requires-channel="http" />
<sec:intercept-url pattern="/**"
requires-channel="http" access="hasRole('authenticated')" />
<sec:form-login login-page="/login.htm"
default-target-url="/index.htm" authentication-failure-url="/login.htm?error=true"
always-use-default-target="true" />
<sec:logout logout-url="/logout.htm" delete-cookies="JSESSIONID" invalidate-session="true" />
<sec:anonymous/>
<sec:remember-me use-secure-cookie="true" />
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="johnny" password="johnny" authorities="authenticated, admin" />
<sec:user name="charlie" password="charlie"
authorities="authenticated" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
</beans>
任何帮助将不胜感激。 提前谢谢!
答案 0 :(得分:1)
我发现此问题的解决方法是禁用Spring Security的默认会话固定保护。我必须在我首次描述的XML配置中添加“session-management”元素。
<sec:http auto-config="true">
<!-- ... -->
<sec:session-management session-fixation-protection="none"/>
<!-- ... -->
</sec:http>
除此之外,我们必须提供的“应用程序URL”的URL不是登录URL,而是主页URL,例如不是http://myapp/login.htm但是http://myapp/index.htm。这样做,如果用户已登录或具有记住我的cookie,他们将能够毫无问题地进入并且浏览器继续使用HTTP协议。如果没有,则使用HTTPS将用户重定向到登录页面,并在成功登录后,浏览器正确切换回HTTP。请考虑到这一点,因为如果您直接写入(或单击)登录URL,将始终保持HTTPS。
答案 1 :(得分:0)
可以通过在过滤器链中添加一个更改cookie的过滤器
在配置文件中创建过滤器并将其添加到过滤器链中,如下所示:
<bean name="httpsCookieFilter" class="bla.bla.bla.HttpsCookieFilter"/>
<security:http auto-config="false" entry-point-ref="authenticationEntryPoint">
...
<security:custom-filter position="FIRST" ref="httpsCookieFilter" />
...
</security:http>
您的过滤器代码看起来像这样
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Sessions created under HTTPS, for which the session cookie is marked as “secure”, cannot subsequently be used under
* HTTP. The browser will not send the cookie back to the server and any session state will be lost (including the
* security context information)
*
* Tomcat tracks user sessions with the help of the JSESSIONID cookie. If you enter into HTTPS with Tomcat, the cookie
* will come back with the secure property being set to true. Subsequently when the redirection to http occurs, the
* browser will not transmit the JSESSIONID cookie and you'll get a new session.
*
* This filter overrides the default Tomcat JSESSIONID behaviour
*/
public class HttpsCookieFilter implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest) request;
final HttpServletResponse httpResponse = (HttpServletResponse) response;
final HttpSession session = httpRequest.getSession(false);
if (session != null) {
final Cookie sessionCookie = new Cookie("JSESSIONID", session.getId());
sessionCookie.setMaxAge(-1);
sessionCookie.setSecure(false);
sessionCookie.setPath(httpRequest.getContextPath());
httpResponse.addCookie(sessionCookie);
}
chain.doFilter(request, response);
}
}