Довольно тривиальная задача, как мне казалось, сделать логин на https-соединении с дальнейшим редиректом на страницу доступную по обычному http-каналу. Для реализации такого решения использовался Spring Security 2.0.4. Однако, все оказалось не так просто.
Для начала приведу свою настройку security-контекста:
<sec:http auto-config="true">
<sec:intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
<sec:intercept-url pattern="/index.jsp" access="ROLE_PLAYER" requires-channel="http"/>
<sec:form-login login-page="/login.jsp" default-target-url="/index.jsp" />
</sec:http>
Конфигурация правильная, только вот редирект не работает. Проблема в том, что после успешной аутентификации, меня перебрасывает обратно на login.jsp.
Воспользовашись HttpWatch-ем, я выяснил, что проблема в том, что при переходе, допустим, с линка https://localhost:8443/login.jsp
на линк http://localhost:8080/index.jsp
, jsessionid передавалась в куке через http-заголовок, а не через урл, как полагается в этом случае. Поэтому Spring Security не видел ранее созданной сесси и создавал свою. Кстати, по умолчанию, после успешной аутентификации он создает новую сессию, дабы предотвратить атаку Session Fixation.
Я завел на это багу http://jira.springframework.org/browse/SEC-1019. Не знаю, когда она будет закрыта, думаю, что не скоро. Поэтому могу предложить свое, временное, решение этой проблемы.
В конфигурации security-контекста пишем:
<sec:http entry-point-ref="authEntryPoint">
<sec:anonymous/>
<sec:port-mappings>
<sec:port-mapping http="8080" https="8443"/>
</sec:port-mappings>
<sec:intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
<sec:intercept-url pattern="/index.jsp" access="ROLE_PLAYER" requires-channel="http"/>
</sec:http>
<bean id="authEntryPoint" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
</bean>
<bean id="authFilter" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
<sec:custom-filter position="AUTHENTICATION_PROCESSING_FILTER" />
<property name="filterProcessesUrl" value="/j_spring_security_check"/>
<property name="defaultTargetUrl" value="/"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="targetUrlResolver">
<bean class="ru.someone.security.ExTargetUrlResolverImpl">
<property name="url" value="/index.jsp"/>
</bean>
</property>
</bean>
<sec:authentication-manager alias="authenticationManager"/>
Столько xml-я пришлось написать лишь для того, чтобы использовать свою реализацию org.springframework.security.ui.TargetUrlResolver
, по-другому никак. Вот собственно и сама реализация этого интерфейса:
package ru.someone.security;
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.Authentication;
import org.springframework.security.ui.TargetUrlResolverImpl;
import org.springframework.security.ui.savedrequest.SavedRequest;
public class ExTargetUrlResolverImpl extends TargetUrlResolverImpl {
private String url;
@Override
public String determineTargetUrl(SavedRequest savedRequest, HttpServletRequest request,
Authentication auth) {
String sessionId = request.getSession().getId();
return url + ";jsessionid=" + sessionId;
}
public void setUrl(String url) {
this.url = url;
}
}
3 комментария:
Идентификатор сессии в url несекьюрно (session-fixation и утекание через referrer на внешних ссылках) и ненадёжно, т.к. на каждой ссылке надо не забывать прогнать их через добавлятор идентификатора.
К тому же, как вам написали в баге, они это делают.
Ну если говорить о несекьюрности, то можно начать с того, что переключение на http уже не безопасно само по себе. Какая разница через что передавать sessionid, если я возьму снифер и выловлю его... А по поводу баги, я знаю, что они так и делают, только вот не работает ничего, потому что в HttpRequest.redirectUrl не занимается выставлением jsessionid при переключении каналов... Это вроде как нелепая причина, с их стороно лишь бы не фиксить, а фикс там простой. А что такое "добавлятор идентификатора"?
Вам же объяснили, что через реферер. И без всякого сниферра утечет.
Отправить комментарий