[SPRING] Spring 보안은 UserDetails 객체를 반환하지 않으며, 사용자 이름 만 반환합니다.
SPRINGSpring 보안은 UserDetails 객체를 반환하지 않으며, 사용자 이름 만 반환합니다.
내 권한 구현이 완료되었다고 생각했지만 UserDetails 객체를 검색하려고 시도 할 때 사용자 이름이 모두 표시됩니다.
나는 다음과 같은 세부 사항으로 oauth를 사용하고있다.
AuthenticationManager 구성 :
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
이렇게하면 내 userDetailsService로 디버깅 할 수 있습니다.
@Service
public class UserServiceImpl implements UserService, UserDetailsService {
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
MyUser persistedUser = userRepository.findByEmail(email);
if (persistedUser == null) {
throw new UsernameNotFoundException(String.format("The email %s doesn't exist", email));
}
List<GrantedAuthority> authorities = new ArrayList<>();
MyUser inMemoryUser = new MyUser(persistedUser.getEmail(), null, persistedUser.getEnabled(), false,
false, false, authorities);
return inMemoryUser;
}
}
이것으로 정상적으로 끝나고 내 의뢰인은 JWT를 돌려 받게됩니다. 하지만 나중에 컨트롤러 메서드를 디버깅 할 때 다음과 같은 문제점을 발견했습니다.
@GetMapping
public @ResponseBody Iterable<Curriculum> getMyCurriculums(@AuthenticationPrincipal MyUser injectedUser) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
MyUser principle = (MyUser) auth.getPrincipal();
return curriculumService.findByUser(principle);
}
이 경우, injectedUser = null, auth는 OAuth2Authentication이며 원칙은 사용자 이름 인 String입니다. MyUser 여야합니다.
해결법
-
==============================
1.jwt 토큰을 MyUser 객체로 디코딩하도록 Spring Security를 설정해야한다.
jwt 토큰을 MyUser 객체로 디코딩하도록 Spring Security를 설정해야한다.
먼저 사용자 정의 OAuth2Authentication을 정의하여 MyUser를 캡슐화하십시오.
public class OAuth2AuthenticationUser extends OAuth2Authentication { private MyUser myUser; public OAuth2AuthenticationUser(OAuth2Request storedRequest, Authentication userAuthentication) { super(storedRequest, userAuthentication); } public MyUser getMyUser() { return myUser; } public void setMyUser(MyUser) { this.myUser= myUser; } }
그런 다음 보안 구성 클래스에서 다음과 같이 jwt 토큰 디코딩을 구성합니다.
@Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey("SIGNING_KEY"); converter.setAccessTokenConverter(getAuthenticationAccessTokenConverter()); return converter; } private DefaultAccessTokenConverter getAuthenticationAccessTokenConverter() { return new DefaultAccessTokenConverter() { @Override public OAuth2Authentication extractAuthentication(Map<String, ?> map) { OAuth2Authentication authentication = (OAuth2Authentication) super.extractAuthentication(map); OAuth2AuthenticationUser authenticationUser = new OAuth2AuthenticationUser(authentication.getOAuth2Request(), authentication.getUserAuthentication()); MyUser myUser = new MyUser(); // Example properties myUser.setId(map.get("id") != null ? Long.valueOf(map.get("id").toString()) : null); myUser.setUsername(map.get("user_name") != null ? map.get("user_name").toString() : null); myUser.setFullName(map.get("fullName") != null ? map.get("fullName").toString() : null); myUser.setCustomerId(map.get("customerId") != null ? Long.valueOf(map.get("customerId").toString()) : null); myUser.setCustomerName(map.get("customerName") != null ? map.get("customerName").toString() : null); // More other properties authenticationUser.setMyUser(myUser); return authenticationUser; } }; }
그리고 다음과 같이 스프링 보안 컨텍스트에서 MyUser 객체에 액세스 할 수 있습니다.
private static MyUser getMyUser() { OAuth2AuthenticationUser authentication = (OAuth2AuthenticationUser) SecurityContextHolder.getContext().getAuthentication(); return (authentication != null && authentication.getMyUser() != null ? authentication.getMyUser() : new MyUser()); }
이것은 사용자 정보에 대한 데이터베이스 액세스가 최소화되고 jwt 토큰 만 있으면 stateless 환경에 적합합니다.
from https://stackoverflow.com/questions/47805115/spring-security-not-returning-userdetails-object-only-username by cc-by-sa and MIT license