Programming & Solution/Java
[SpringBoot] OAUTH2 설정
GOD동하
2019. 8. 22. 14:53
OAUTH2 설정
Security Config 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
// 얘는 Resource Server에서 해줄거라 이제 필요는 없음
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().frameOptions().disable()
.and()
.csrf().disable().anonymous()
.and()
.authorizeRequests().antMatchers("/oauth/**").permitAll()
.antMatchers("/h2-console").permitAll()
.anyRequest().permitAll();
}
@Bean
public PasswordEncoder passwordEncoder () {
return new BCryptPasswordEncoder();
}
}
|
Authorization Server 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private MyClientDetailsService myClientDetailsService;
@Autowired
private DataSource dataSource;
@Autowired
public PasswordEncoder passwordEncoder;
// jdbc 로 client 정보 관리
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
}
// credential 검증 시 사용할 spring security의 authenticationManager를 주입
// 토큰은 DB로 저장하도록 설정
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore());
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setReuseRefreshToken(false);
defaultTokenServices.setClientDetailsService(myClientDetailsService);
endpoints.tokenServices(defaultTokenServices)
;
}
// token을 DB에서 관리함
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
}
|
Resource Server 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
// Resource 사용에 대한 허용 rule
@Override
public void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable()
.and()
.csrf().disable().anonymous()
.and()
.authorizeRequests().antMatchers("/h2-console").permitAll()
.antMatchers("/test").authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
// ResourceServerConfigurer 인터페이스에 여기서 적어도 resourceId는 설정하라고 해서..
// 이 Resource를 식별할 수 있는 ID고 OAUTH_CLIENT_DETAILS 에서 사용하는 Resource 정보를 같이 관리한다
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("my_resource");
}
}
|
JDBC용 ClientDetailsService 생성
1
2
3
4
5
6
|
@Service
public class MyClientDetailsService extends JdbcClientDetailsService {
public MyClientDetailsService(DataSource dataSource) {
super(dataSource);
}
}
|
TestController 생성
resource server의 [13 Line] 에서 oauth 권한이 있어야 사용할 수 있는 resource로 지정
1
2
3
4
5
6
7
|
@RestController
public class TestController {
@GetMapping("/test")
public String test() {
return "test";
}
}
|
토큰 발급 TestCase 생성
기본적으로 [17 Line] 의 /oauth/token URI를 통해 토큰을 발급 받는다.
(여기선 BasicAuth 형태로 인증을 한 후 Token을 발급 받는 형태)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class AuthServerConfigTest {
@Autowired
PasswordEncoder passwordEncoder;
@Autowired
protected MockMvc mockMvc;
@Test
public void getAuthToken() throws Exception {
// Given
String clientId = "dong";
String clientSecret = "dong";
// When
mockMvc.perform(post("/oauth/token")
.with(httpBasic(clientId, clientSecret))
.param("grant_type", "client_credentials"))
// Then
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("access_token").exists());
}
}
|
기본적으로 InMemory 베이스가 아닌 JDBC 형태로 갈 경우 테이블은 아래 링크에서 확인할 수 있는 스키마 형태로 만들어야 한다. spring security oauth2 에서 제공해주는 기본적인 형태로 커스텀해서 사용도 가능함.
※ OAUTH2 스키마 참조
spring-projects/spring-security-oauth
Support for adding OAuth1(a) and OAuth2 features (consumer and provider) for Spring web applications. - spring-projects/spring-security-oauth
github.com