이전까지는 짧은 문자열 토큰을 받았다면, 이제 JWT를 이용해 길고.. 정보가 담긴... 토큰을 받아보려 한다!
JWT토큰으로 발급받으면 더 이상 데이터베이스에 토큰을 저장하지 않아도 된다...?
0. 의존성 추가
jwt를 사용하기 위해서는 spring-securiti-jwt를 추가해야 함
// JWT
implementation group: 'org.springframework.security', name: 'spring-security-jwt', version: '1.1.1.RELEASE'
1. CustomUserDetailService만들기
그런데 그 전에..! User를 수정해준다 UserDetails를 상속받아 오버라이딩 해주기..
@Data
@ToString
public class User implements UserDetails {
private String id;
private String name;
private String password;
private String authorities;
@Override
public String getUsername() {
return name;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
ArrayList<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
authList.add(new SimpleGrantedAuthority(authorities));
return authList;
}
}
그리고 이제 진짜로 CustomUserDetailService를 작성
@AllArgsConstructor
@Service
public class CustomUserDetailService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
private final AccountStatusUserDetailsChecker detailsChecker = new AccountStatusUserDetailsChecker();
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.findByName(username);
if(user == null)
throw new UsernameNotFoundException("유저 정보 찾을 수 없음");
return user;
}
}
2. Ouath2AuthorizationConfig 수정
JWT를 사용하겠다는 설정을 해준다.
userDetailsService를 통해 기한이 만료된 access_token을 refresh_token을 이용해 갱신할 수 있게됨!
@AllArgsConstructor
@Configuration
@EnableAuthorizationServer // OAuth2 인증 서버를 사용하겠다는 뜻
public class Oauth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
private AuthenticationManager authenticationManager; // grant_type password를 사용하려면 필수
private DataSource dataSource;
private PasswordEncoder passwordEncoder;
private CustomUserDetailService customUserDetailService;
/* OAuth2 서버가 작동하기 위한 EndPoint에 대한 정보 설정 */
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore())
.authenticationManager(authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter())
.userDetailsService(customUserDetailService);
}
/* token store로 JWTTokenStore를 사용하겠다 */
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
/* JWT 디코딩 하기 위한 설정 */
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey("jwtKey");
return jwtAccessTokenConverter;
}
/* 클라이언트 대한 정보를 설정하는 부분 */
/* jdbc(DataBase)를 이용하는 방식 */
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}
}
3. 테스트
우선 grant_type을 password로 정하고, 토큰을 발급받는다.
response값을 보면 알겠지만 access_token의 기한이 매우 짧다. (29초 남음)
이제 refresh_token을 이용해 access_token을 갱신(재발급)해보자
grant_type을 refresh_token으로 설정하고, refresh_token값을 보내면 access_token을 갱신할 수 있다.
(위의 캡쳐와 비교하면 달라져있음!)
📌 계속 refresh_token이 안온다...?
=> grant_type에 refresh_token이 있는지 확인하기! inMemory형식이면 (... , "refresh_token)이런식으로 추가하고,
JDBC를 이용하면 아래처럼 콤마(,)로 구분해 여러 개를 작성할 수 있다!
📌 access_token 유효시간 설정
+) 참고
'STUDY > Spring' 카테고리의 다른 글
Spring Boot | Spring Security OAuth2 (5) 서버 나누기 (Multi Module) (0) | 2021.03.10 |
---|---|
Spring Boot | 멀티 모듈 프로젝트 (Multi Module) (0) | 2021.03.10 |
Spring Boot | Spring Security OAuth2 (3) JDBC방식으로 바꾸기 (0) | 2021.03.09 |
Spring Boot | Spring Security OAuth2 (2) grant_type password, postman / Curl로 테스트 (0) | 2021.03.09 |
Spring Boot | Spring Security OAuth2 (1) 설정 및 테스트 (inMemory) (0) | 2021.03.08 |