Как добавить пользовательский фильтр после авторизации пользователя в весеннем приложении
Я новичок в Spring Security 3. Я использую роли для входа пользователей.
Я хочу добавить некоторое значение сеанса после авторизации пользователя в приложении. Может быть, мне нужен какой-то фильтр, чтобы он перенаправлял в мой метод, который добавляет значение сеанса. Я настроил свой файл security.xml, но не уверен, правильно ли я поступаю. Любые примеры в этом направлении помогут. Какой класс фильтра я должен использовать? Как мне настроить файл security.xml?
<custom-filter ref="authenticationFilter" after="FORM_LOGIN_FILTER "/>
<beans:bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="filterProcessesUrl" value="/j_spring_security_check" />
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler" ref="successHandler" />
</beans:bean>
<beans:bean id="successHandler" class="org.dfci.sparks.datarequest.security.CustomAuthorizationFilter"/>
Мой метод класса фильтра мне нужно добавить некоторое значение сеанса.
public class CustomAuthorizationFilter implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
Set<String> roles = AuthorityUtils.authorityListToSet(authentication
.getAuthorities());
if (roles.contains("ROLE_USER")) {
request.getSession().setAttribute("myVale", "myvalue");
}
}
}
Изменить код
Я изменил свой файл security.xml и файл классов
<custom-filter ref="authenticationFilter" after="FORM_LOGIN_FILTER "/>
public class CustomAuthorizationFilter extends GenericFilterBean {
/*
* ServletRequestAttributes attr = (ServletRequestAttributes)
* RequestContextHolder.currentRequestAttributes(); HttpSession
* session=attr.getRequest().getSession(true);
*/
@Autowired
private UserService userService;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(request, response);
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession(true);
Authentication authentication = SecurityContextHolder
.getContext().getAuthentication();
Set<String> roles = AuthorityUtils
.authorityListToSet(authentication.getAuthorities());
User user = null;
if (true) {
session.setAttribute("Flag", "Y");
}
}
} catch (IOException ex) {
throw ex;
}
}
}
Который вызывает каждый URL. Есть ли альтернатива вызывать метод фильтра только один раз, когда пользователь проходит аутентификацию?
2 ответа
Наконец я смог решить мою проблему. Вместо использования фильтра я добавил обработчик, который вызывает только успешный вход в систему.
Следующая строка добавлена в security.xml
<form-login login-page="/" authentication-failure-url="/?login_error=1" default-target-url="/" always-use-default-target="false"
authentication-success-handler-ref="authenticationSuccessHandler"/>
<logout />
<beans:bean id="authenticationSuccessHandler" class="security.CustomSuccessHandler"/>
Также я добавил один пользовательский обработчик, который добавляет атрибут сессии.
package security;
import java.io.IOException;
import java.security.GeneralSecurityException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
public class CustomSuccessHandler extends
SavedRequestAwareAuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(final HttpServletRequest request,
final HttpServletResponse response, final Authentication authentication)
throws IOException, ServletException {
super.onAuthenticationSuccess(request, response, authentication);
HttpSession session = request.getSession(true);
try {
if (CurrentUser.isUserInRole("USER")) {
session.setAttribute("Flag", "user");
}
} catch (Exception e) {
logger.error("Error in getting User()", e);
}
}
}
Вы можете использовать стандартный Java-фильтр (я имею в виду реализовать интерфейс фильтра). Просто поместите его после фильтра аутентификации в web.xml (это означает, что он будет добавлен позже в цепочку фильтров и будет вызываться после цепочки фильтров безопасности).
public class CustomFilter implements Filter{
@Override
public void destroy() {
// Do nothing
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if (roles.contains("ROLE_USER")) {
request.getSession().setAttribute("myVale", "myvalue");
}
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// Do nothing
}
}
Фрагмент web.xml:
<!-- The Spring Security Filter Chain -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!-- Pay attention to the url-pattern -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<!-- <dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher> -->
</filter-mapping>
<!-- Your filter definition -->
<filter>
<filter-name>customFilter</filter-name>
<filter-class>com.yourcompany.test.CustomFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>customFilter</filter-name>
<url-pattern>/VacationsManager.jsp</url-pattern>
</filter-mapping>