2017-12-14 1 views
2

내 인증 구현이 완료되었다고 생각했지만 UserDetails 객체를 검색하려고 시도 할 때 사용자 이름이 모두 나타납니다.스프링 보안이 UserDetails 객체를 반환하지 않고 사용자 이름 만

다음 내용과 함께 oauth를 사용하고 있습니다.

AuthenticationManager에 구성이 완료로

@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); 
} 

을, 내 경우 UserDetailsService으로 디버깅 할 수 있습니다 :이 잘 완료하고 내 클라이언트가 JWT를 돌아 오기

@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; 
    } 
} 

. 하지만 나중에 컨트롤러 메서드를 디버깅 할 때 다음과 같은 문제점을 발견했습니다. 이 경우

@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가, 인증은 OAuth2Authentication이며, 원리는 문자열입니다 - 사용자 이름. MyUser이어야합니다.

+0

그리고 문제는 ...... ??? –

답변

3

jwt 토큰을 MyUser 오브젝트로 디코딩하도록 스프링 보안을 구성해야합니다.

먼저 MyUser을 캡슐화하는 맞춤 OAuth2Authentication을 정의하십시오. 다음과 같이 보안 구성 클래스 구성에서 다음

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 환경에 적합합니다.

관련 문제