Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom filter after user authorize in spring application

I am a newbie to Spring Security 3. I am using roles for users to login.

I want to add some session value after a user is authorized into the application. Maybe I need some filter so that it redirects to my method which adds some session value. I have configured my security.xml file but I am not sure whether I am doing right things. Any examples in that direction would help. Which Filter Class should I use? How should I configure security.xml file?

<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"/>

My filter class method I need to add some session value.

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

I have modified my security.xml file and class file

<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;
        }
    }

}

Which invokes each and every URL. Is it any alternative to call filter method only once when a user is authenticated?

like image 599
Raje Avatar asked Jul 05 '12 04:07

Raje


2 Answers

Finally I was able to resolved my problem. Instead of using filter I have added handler which only invokes for successful login.

Following line is added in 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"/>

Also I have added one custom handler which add session attribute.

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);
        } 
    }

}
like image 61
Raje Avatar answered Nov 07 '22 15:11

Raje


You can use standart java filter (I mean implement Filter interface). Just place it after authentification filter in web.xml (this means that it will go later in the filter chain and will be called after security filter chain).

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
    }

}

Fragment of 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>
like image 21
dimas Avatar answered Nov 07 '22 15:11

dimas