Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security: Access the current authenticated User inside a servlet Filter

I recently started learning about Spring Security and today I stepped on this basic (I believe) question: Why can't I access the current Principal inside a Servlet Filter as demonstrated in the class below:

package com.acme.test;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Component
public class TestFilter implements Filter {

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub

    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
     * javax.servlet.ServletResponse, javax.servlet.FilterChain)
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        SecurityContext securityContext = SecurityContextHolder.getContext();
        Authentication auth = securityContext.getAuthentication();

        // auth is null here

        chain.doFilter(request, response);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.Filter#destroy()
     */
    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}

The Authentication object retrieved with Authentication auth = securityContext.getAuthentication(); is null. While using the above snippet inside an MVC @Controller works just fine (as expected).

Why is this happening?

like image 311
dimi Avatar asked Sep 30 '14 17:09

dimi


3 Answers

inside doFilter:

HttpServletRequest request = (HttpServletRequest) request;
HttpSession session = request.getSession(false);

SecurityContextImpl sci = (SecurityContextImpl) session.getAttribute("SPRING_SECURITY_CONTEXT");

if (sci != null) {
        UserDetails cud = (UserDetails) sci.getAuthentication().getPrincipal();
        // do whatever you need here with the UserDetails
}

Hope this helps

like image 85
Vipul Paralikar Avatar answered Oct 22 '22 12:10

Vipul Paralikar


The following snippet works and provides a Principal instance:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;

    Principal principal = req.getUserPrincipal();

    if (principal != null) {
        // do something with the Principal
    }

    chain.doFilter(request,  response);
}
like image 16
Shimakaze Avatar answered Oct 22 '22 13:10

Shimakaze


import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null) {
  if (authentication.getPrincipal() instanceof UserDetails) {
    UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
    return springSecurityUser.getUsername();
  } else if (authentication.getPrincipal() instanceof String) {
    return (String) authentication.getPrincipal();
  }
}
return null;
like image 5
Ariel Avatar answered Oct 22 '22 12:10

Ariel