8

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?

Melebius
  • 6,183
  • 4
  • 39
  • 52
Raje
  • 3,285
  • 15
  • 50
  • 70
  • What is the problem with the above code? Are you not getting session myValue attribute inside login success url? – Sunil Chavan Jul 05 '12 at 06:34
  • @SunilChavan : It call this filter before user is authenticate. – Raje Jul 05 '12 at 06:57
  • How can you say that? See the (API)[http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/authentication/AuthenticationSuccessHandler.html] details. It clearly says after successful authentication it calls onAuthenticationSuccess method – Sunil Chavan Jul 05 '12 at 07:15
  • @SunilChavan, Thanks, Link is not working. – Raje Jul 05 '12 at 08:28

2 Answers2

12

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

}
Julien C.
  • 946
  • 8
  • 22
Raje
  • 3,285
  • 15
  • 50
  • 70
  • i am calling a common function from hear,but it return null pointer exception which runing jdbctemplate. – Zigri2612 May 04 '16 at 09:49
1

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>
dimas
  • 6,033
  • 36
  • 29
  • Thanks for giving example. I follow same steps as you mentioned. I have modified my code but that filter method call for each and every url. Is it any alternative to call only once when user is authenticate? – Raje Jul 06 '12 at 03:31
  • If I understand you correct, you should set correct url-pattern for filter (for example your login page /login.jsp). In such case filter will intercept only request for your login page. For other urls filter will not execute. – dimas Jul 06 '12 at 06:10
  • I tried using /login.jsp but still it does not call my filter method only for login. – Raje Jul 06 '12 at 10:35
  • Actually, I think that you miss something. I have just tested this case. I had two pages: login.jsp and customPage.jsp (gwt application). And all is working perfect. Filter intercepts only requests for /login.jsp. – dimas Jul 06 '12 at 11:24
  • Thanks for helping. Please check out my answer. For Login page we have only "/". I have implemented it using handler. PLease see my answer below. – Raje Jul 11 '12 at 04:30