복붙노트

[SPRING] 봄 보안에서 현재 로그인 한 사용자 객체를 얻는 방법?

SPRING

봄 보안에서 현재 로그인 한 사용자 객체를 얻는 방법?

나는 봄 보안 버전 3.1.4를 사용하고 있습니다. 릴리스. 현재 로그인 한 사용자 개체에 어떻게 액세스합니까?

SecurityContextHolder.getContext().getAuthentication().getPrinciple()

사용자 개체가 아니라 사용자 이름을 반환합니다. 그렇다면 반환 된 Username을 어떻게 사용하고 UserDetails 객체를 얻을 수 있습니까?

나는 다음 코드를 시도했다 :

public UserDetails getLoggedInUser(){

    final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken))
    {
        if(auth.getDetails() !=null)
            System.out.println(auth.getDetails().getClass());
        if( auth.getDetails() instanceof UserDetails)
        {
            System.out.println("UserDetails");
        }
        else
        {
            System.out.println("!UserDetails");
        }
    }
    return null;
}

결과는 다음과 같습니다.

[2015-08-17 19:44:46.738] INFO  http-bio-8443-exec-423   System.out    class org.springframework.security.web.authentication.WebAuthenticationDetails 
[2015-08-17 19:44:46.738] INFO  http-bio-8443-exec-423   System.out    !UserDetails

AuthenticationFilter 클래스는 다음과 같습니다.

public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
    public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
    private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
    private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
    private boolean postOnly = true;

    public CustomUsernamePasswordAuthenticationFilter() {
        super("/j_spring_security_check");
    }

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        String username = obtainUsername(request);
        String password = obtainPassword(request);
        if (username == null) {
            username = "";
        }
        if (password == null) {
            password = "";
        }
        username = username.trim();
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);
        if(this.getAuthenticationManager()==null){
            logger.info("Authentication manager is null.");
        } else {
            logger.info("Authentication manager was "+this.getAuthenticationManager().getClass().getName()); 
        }
        return this.getAuthenticationManager().authenticate(authRequest);
    }

    protected String obtainPassword(HttpServletRequest request) {
        return request.getParameter(passwordParameter);
    }

    protected String obtainUsername(HttpServletRequest request) {
        return request.getParameter(usernameParameter);
    }

    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }

    public void setUsernameParameter(String usernameParameter) {
        this.usernameParameter = usernameParameter;
    }

    public void setPasswordParameter(String passwordParameter) {
        this.passwordParameter = passwordParameter;
    }

    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }

    public final String getUsernameParameter() {
        return usernameParameter;
    }

    public final String getPasswordParameter() {
        return passwordParameter;
    }
}

AuthenticationProvider는 다음과 같습니다.

@Component
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
    private MyUserDetailsService userDetailsService;

    public MyUserDetailsService getUserDetailsService() {
        return userDetailsService;
    }

    public void setUserDetailsService(MyUserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void additionalAuthenticationChecks(UserDetails arg0,
            UsernamePasswordAuthenticationToken arg1)
            throws AuthenticationException {

    }

    @Override
    protected UserDetails retrieveUser(String arg0,
            UsernamePasswordAuthenticationToken arg1)
            throws AuthenticationException {
        return userDetailsService.loadUserByUsername(arg0);
    }
}

UserDetails 클래스는 다음과 같습니다.

    public class MyUserDetailsService implements UserDetailsService {       
    private final Map<String, UserDetails> usersList;

    public MyUserDetailsService() {
        Collection<GrantedAuthority> authorityList;
        final SimpleGrantedAuthority supervisorAuthority = new SimpleGrantedAuthority("supervisor");
        final SimpleGrantedAuthority userAuthority = new SimpleGrantedAuthority("user");
        usersList = new TreeMap<String, UserDetails>();

        authorityList = new ArrayList<GrantedAuthority>();
        authorityList.add(supervisorAuthority);
        authorityList.add(userAuthority);
        usersList.put("admin", new User("admin", "admin", authorityList));

        authorityList = new ArrayList<GrantedAuthority>();
        authorityList.add(userAuthority);
        usersList.put("peter", new User("peter", "password123", authorityList));

        //probably don't use this in production
        for(Map.Entry<String, UserDetails> user : usersList.entrySet()){
            logger.info(user.getValue().toString());
        }
    }

    @Override
    public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException {
        UserDetails ud = usersList.get(username);
        if (ud != null) {
            logger.info("loadUserByUsername: found match, returning "
                    + ud.getUsername() + ":" + ud.getPassword() + ":"
                    + ud.getAuthorities().toString());
            return new User(ud.getUsername(), ud.getPassword(),
                    ud.getAuthorities());
        }

        logger.info("loadUserByUsername: did not find match, throwing UsernameNotFoundException");
        throw new UsernameNotFoundException(username);
    }
}

해결법

  1. ==============================

    1.

    SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    

    현재 사용자 객체를 반환합니다. User, UserDetails 또는 사용자 정의 사용자 객체 일 수 있습니다. 사용자 지정 개체 인 경우 반환 개체를 UserDetails 또는 사용자 개체로 캐스팅해야합니다.

    또는 인증 또는 교장을 직접 컨트롤러에 삽입 할 수 있습니다. 원리는 UserDetails / 사용자 정의 사용자 객체입니다.

    참고 : UserDetails는 인터페이스입니다.

  2. ==============================

    2.당신은 그것을 같이 사용할 수 있습니다.

    당신은 그것을 같이 사용할 수 있습니다.

    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    
    if (principal instanceof UserDetails) {
    String username = ((UserDetails)principal).getUsername();
    } else {
    String username = principal.toString();
    }
    

    스프링 보안 참조 http://docs.spring.io/spring-security/site/docs/4.0.2.RELEASE/reference/htmlsingle/#obtaining-information-about-the-current-user

  3. ==============================

    3.방금 한 걸음 더 나아 갔다. SecurityContextHolder.getContext (). getAuthentication ()은 Authentication 객체를 반환합니다. 사용자를 인증 한 방법과 인증을 구현하는 구체적인 클래스가 무엇인지를 알아야합니다. 이 클래스가 AbstractAuthenticationToken (모든 Spring에서 제공 한 구현)의 하위 클래스이고 getDetails ()가 UserDetails를 반환한다고 가정하면 다음을 사용할 수 있습니다.

    방금 한 걸음 더 나아 갔다. SecurityContextHolder.getContext (). getAuthentication ()은 Authentication 객체를 반환합니다. 사용자를 인증 한 방법과 인증을 구현하는 구체적인 클래스가 무엇인지를 알아야합니다. 이 클래스가 AbstractAuthenticationToken (모든 Spring에서 제공 한 구현)의 하위 클래스이고 getDetails ()가 UserDetails를 반환한다고 가정하면 다음을 사용할 수 있습니다.

    AbstractAuthenticationToken auth = (AbstractAuthenticationToken)
        SecurityContextHolder.getContext().getAuthentication();
    UserDetails details = (UserDetails) auth.getDetails();
    
  4. ==============================

    4.컨트롤러에 인증 인터페이스를 삽입하고 로그인 된 사용자의 사용자 이름을 얻을 수 있습니다 (예 :

    컨트롤러에 인증 인터페이스를 삽입하고 로그인 된 사용자의 사용자 이름을 얻을 수 있습니다 (예 :

    @Controller
    public class SomeController {
    
        @GetMapping(value = "/username")
        @ResponseBody
        public String currentUserName(Authentication authentication) {
    
            if (authentication != null) {
                return authentication.getName();
    
            } else {
                return "";
            }
        }
    }
    
  5. from https://stackoverflow.com/questions/32052076/how-to-get-the-current-logged-in-user-object-from-spring-security by cc-by-sa and MIT license