Как добавить пользовательский фильтр после авторизации пользователя в весеннем приложении

Я новичок в 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");
        }
    }
}

Edit Code

Я изменил свой файл 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. Есть ли альтернатива вызывать метод фильтра только один раз, когда пользователь проходит аутентификацию?

 Sunil Chavan05 июл. 2012 г., 09:15
Как ты можешь говорить такое? Смотрите (API) [static.springsource.org/spring-security/site/docs/3.0.x/apidocs/… подробности. Он ясно говорит, что после успешной аутентификации он вызывает метод onAuthenticationSuccess
 Raje05 июл. 2012 г., 10:28
@SunilChavan, спасибо, ссылка не работает.
 Raje05 июл. 2012 г., 08:57
@SunilChavan: он вызывает этот фильтр, прежде чем пользователь проходит аутентификацию.
 Sunil Chavan05 июл. 2012 г., 08:34
В чем проблема с приведенным выше кодом? Вы не получаете атрибут myValue сессии в 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);
        } 
    }

}
 04 мая 2016 г., 11:49
Я вызываю обычную функцию из слышать, но она возвращает исключение нулевого указателя, который работает jdbctemplate.
 04 мая 2016 г., 11:50
исключение Threadpoolexecutor неизвестный источник

Вы можете использовать стандартный 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>
 Raje06 июл. 2012 г., 12:35
Я попытался использовать /login.jsp, но он не вызывает мой метод фильтра только для входа в систему.
 06 июл. 2012 г., 08:10
Если я правильно понимаю, вы должны установить правильный шаблон URL для фильтра (например, страницу входа /login.jsp). В этом случае фильтр будет перехватывать только запрос на вашу страницу входа. Для других URL фильтр не будет выполнен.
 Raje06 июл. 2012 г., 05:31
Спасибо за пример. Я следую тем же шагам, что и вы. Я изменил свой код, но этот вызов метода фильтра для каждого URL. Есть ли альтернатива звонить только один раз, когда пользователь проходит аутентификацию?
 06 июл. 2012 г., 13:24
На самом деле, я думаю, что вы что-то упускаете. Я только что проверил этот случай. У меня было две страницы: login.jsp и customPage.jsp (приложение gwt). И все работает отлично. Фильтр перехватывает только запросы на /login.jsp.
 05 июл. 2012 г., 09:12
Я редактирую пример во многом твоем случае.

Ваш ответ на вопрос