이전까지 inMemory방식이었지만, 이제 JDBC방식으로 바꿔본다..
0. DB설정 및 테이블 생성
application.yml혹은 application.properties파일에서 설정해주기!
아래 링크의 sql을 참고해서 만들면 되는데,
일단 oauth_client_details 테이블(클라이언트 정보가 담길 테이블)만 생성해주었다.
1. Oauth2AuthorizationConfig 수정
inMemory방식으로 설정해둔 부분을 주석처리 하거나 삭제한 후, jdbc방식으로 설정해준다.
passwordencoder를 설정해두었기 때문에 DB에도 인코딩 된 비밀번호 값이 들어가야한다.
@AllArgsConstructor
@Configuration
@EnableAuthorizationServer // OAuth2 인증 서버를 사용하겠다는 뜻
public class Oauth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager;
private DataSource dataSource;
private PasswordEncoder passwordEncoder;
/* OAuth2 서버가 작동하기 위한 EndPoint에 대한 정보 설정 */
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
/* 클라이언트 대한 정보를 설정하는 부분 */
/* jdbc(DataBase)를 이용하는 방식 */
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}
/* inMemory 방식*/
// @Override
// public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// clients.inMemory()
// .withClient("clientId") // 클라이언트 아이디
// .secret("{noop}clientSecret") // 클라이언트 시크릿
// .redirectUris("http://localhost:8081/oauth2/callback") // 인증 결과를 수신할 URI
// .authorizedGrantTypes("authorization_code", "password") // 인증 방식
// .scopes("read", "write") // 해당 클라이언트의 접근 범위
// .accessTokenValiditySeconds(60 * 60 * 4) // access token 유효 기간 (초 단위)
// .refreshTokenValiditySeconds(60 * 60 * 24 * 120) // refresh token 유효 기간 (초 단위)
// .autoApprove(true); // OAuth Approval 화면 나오지 않게 처리
// }
}
그래서 일단 서버가 시작될 때 인코딩된 값을 출력하도록 해놨다...
@SpringBootApplication
public class Oauth2Application {
public static void main(String[] args) {
SpringApplication.run(Oauth2Application.class, args);
PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
System.out.println("endcode = " + passwordEncoder.encode("clientSecret"));
}
}
그리고 인코딩된 값을 테이블에 insert해주기
insert into oauth_client_details(client_id, resource_ids, client_secret,
scope, authorized_grant_types, web_server_redirect_uri,
authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove)
values("clientId", null, "{bcrypt}$2a$10$WJ1ZVWwZm/lY.hVlrGo4VejG7V7Mwscbdpy/DoEQema6SqZAnX9nm",
"read,write", "authorization_code,password", "http://localhost:8081/oauth2/callback",
"ROLE_USER", 36000, 50000, null, "true");
2. 테스트
http://localhost:8081/oauth/authorize?client_id=clientId&redirect_uri=http://localhost:8081/oauth2/callback&response_type=code&scope=read
포스트맨으로도 잘 된다!
여기까지 잘 되면, 우선 Client 정보를 DB에서 받아와 유효한지 체크할 수 있게 된 것이다!
이제 User정보도 DB에서 조회해 유효한지 체크해보자.. 이 부분은 일반 스프링 시큐리티와 거의 동일
3. USER 테이블 생성 및 INSERT
USER테이블은 자유롭게 만들면 되는데, name, password, role혹은 auth같은 값을 담을 컬럼 정도가 필요함.
여기서도 password인코딩 해주는 것 잊지 말자!
그리고 mapper작성 및 service... 다 합시다..
4. CustomAuthenticationProvider작성
@AllArgsConstructor
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
UserService userService;
private final PasswordEncoder passwordEncoder;
/* 유효한 회원 정보인지 확인하는 부분 */
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
User findUser = userService.findByPk(username);
if(!passwordEncoder.matches(password, findUser.getPassword())) {
throw new BadCredentialsException("비밀번호가 일치하지 않음");
}
List<GrantedAuthority> authorityList = new ArrayList<>();
authorityList.add(new SimpleGrantedAuthority(findUser.getAuthorities()));
return new UsernamePasswordAuthenticationToken(username, password, authorityList);
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
5. SecurityConfig 수정
우선 위에서 작성한 CustomAuthenticationProvider를 불러오고
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
inMemory방식이었던 부분을 주석처리 혹은 삭제한 뒤 아래와 같이 작성한다.
/* DB에서 user 조회 */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
+) 참고
'STUDY > Spring' 카테고리의 다른 글
Spring Boot | 멀티 모듈 프로젝트 (Multi Module) (0) | 2021.03.10 |
---|---|
Spring Boot | Spring Security OAuth2 (4) JWT TokenStore (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 |
Spring Boot | Swagger2 사용 (springfox-boot-starter:3.0.0) (0) | 2021.03.05 |