[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.
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
현재 사용자 객체를 반환합니다. User, UserDetails 또는 사용자 정의 사용자 객체 일 수 있습니다. 사용자 지정 개체 인 경우 반환 개체를 UserDetails 또는 사용자 개체로 캐스팅해야합니다.
또는 인증 또는 교장을 직접 컨트롤러에 삽입 할 수 있습니다. 원리는 UserDetails / 사용자 정의 사용자 객체입니다.
참고 : UserDetails는 인터페이스입니다.
-
==============================
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.방금 한 걸음 더 나아 갔다. 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.컨트롤러에 인증 인터페이스를 삽입하고 로그인 된 사용자의 사용자 이름을 얻을 수 있습니다 (예 :
컨트롤러에 인증 인터페이스를 삽입하고 로그인 된 사용자의 사용자 이름을 얻을 수 있습니다 (예 :
@Controller public class SomeController { @GetMapping(value = "/username") @ResponseBody public String currentUserName(Authentication authentication) { if (authentication != null) { return authentication.getName(); } else { return ""; } } }
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
'SPRING' 카테고리의 다른 글
[SPRING] Spring에서 정적 메서드를 가로 채기하는 방법? (0) | 2019.01.06 |
---|---|
[SPRING] Java Config (no xml)에 SaltSource 등록하는 방법 (0) | 2019.01.06 |
[SPRING] JDBC 유형에 대한 Dialect 매핑이 없습니다 : 1111 (0) | 2019.01.06 |
[SPRING] 봄 사용자 정의 JSF 로그인 페이지, 항상 "잘못된 자격 증명" (0) | 2019.01.06 |
[SPRING] Spring JSP 페이지에서 콜렉션을 사용하는 동안 Hibernate LazyInitializationException이 발생한다. (0) | 2019.01.06 |