Spring Security:访问servlet Filter中当前经过身份验证的User

dim*_*imi 13 spring servlets spring-mvc spring-security

我最近开始学习Spring Security,今天我踩到了这个基本的(我相信)问题:为什么我不能访问Servlet过滤器中的当前Principal,如下面的类所示:

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

    }

}
Run Code Online (Sandbox Code Playgroud)

使用Authentication auth = securityContext.getAuthentication()检索的Authentication对象; 一片空白.虽然在MVC @Controller中使用上面的代码段工作得很好(如预期的那样).

为什么会这样?

Vip*_*kar 20

里面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
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


小智 9

以下代码段工作并提供了一个Principal实例:

@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);
}
Run Code Online (Sandbox Code Playgroud)


Ari*_*iel 5

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;
Run Code Online (Sandbox Code Playgroud)