spring security in action chap.14
14장에서는 리소스 서버를 직접 구현하는 것을 테스트
방법은 총 3가지가 있고
첫번째로
리소스 서버가 직접 권한부여서버를 호출해서 토큰을 검증하는 방식
왜 리소스 서버가 직접 권한부여서버를 호출하냐면
클라이언트가 리소스서버를 호출해서 리소스를 가져올 때 토큰을 사용해서 검증을 하는데
이 토큰이 제대로된 토큰인지 권한부여서버에게 다시 한번 물어보기 위한 용도이다.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
테스트하기 위한 컨트롤 클래스 생성
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello!";
}
}
리소스서버는 간단한 어노테이션을 통해 구현가능
@Configuration
@EnableResourceServer
public class ResourceServerConfig {
}
깃허브 예제소스는 ch14-ex2만 보면됨.
그이후에 13장에서 했던것처럼 토큰 호출
curl -v -XPOST -u client:secret "http://localhost:8080/oauth/token?grant_type=password&username=john&password=12345"
그러면 아래와 같이 토큰 발급
{"access_token":"7d07e441-dd1b-4bf6-9e6d-92f89bd97834","token_type":"bearer","refresh_token":"ce40dcc1-f922-4eb7-ac85-5d1c01f7ab4a","expires_in":43051,"scope":"read"}* Connection #0 to host localhost left intact
그리고 나서 위의 토큰을 이용해서 아래 명령어를 호출하면
curl -v -XPOST -u resourceserver:resourceserversecret "http://localhost:8080/oauth/check_token?token=7d07e441-dd1b-4bf6-9e6d-92f89bd97834"
아래는 응답값
{"active":true,
"exp":1694449928,
"user_name":"john","authorities":["read"],"client_id":"client","scope":["read"]}*
Connection #0 to host localhost left intact
check_token 엔드포인트가 반환한 응답 정보들
-토큰의 현재 활성화 상태와 만료시점
-토큰이 발급된 대상 사용자
-권한
-토큰이 발급된 대상 클라이언트
다시 정리하자면 총 서버를 2개 띄운다.
참고로 깃허브 소스보면 as와 rs가 있는데
as는 권한부여서버
rs는 리소스서버이다.
설명이 이상하게 나와있어서 집중해서 읽어봐야 알 수 있다.
8080 : 권한부여서버(as)
9090 : 리소스서버 (rs)-> 그리고 websecurityconfig가 없어서 실행이 안되는데 as에서 그대로 복사하면됨.
그다음 리소스컨피그는 아래와 같이 간단하게 구현
@Configuration
@EnableResourceServer
public class ResourceServerConfig {
}
그리고 application.properites에서 토큰 검정을 하기 위한 url정보를 적어줌.
server.port=9090
security.oauth2.resource.token-info-uri=http://localhost:8080/oauth/check_token
security.oauth2.client.client-id=resourceserver
security.oauth2.client.client-secret=resourceserversecret
그리고 마지막으로 헤더에 토큰값을 전달하면 hello가 정상적으로 호출되는 것을 볼 수 있다.
C:\Users\user>curl -H "Authorization: Bearer dabaad44-0b92-4c37-a76d-966b7aede097" "http://localhost:9090/hello"
그다음 resourceserverconfig를 구현하는 방법
차이는 어노테이션이 사라짐.
@Configuration
public class ResourceServerConfig
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and().oauth2ResourceServer(
c -> c.opaqueToken(
o -> {
o.introspectionUri("http://localhost:8080/oauth/check_token");
o.introspectionClientCredentials("resourceserver", "resourceserversecret");
})
);
}
}
application.properties에는 설정정보들이 모두빠짐.
server.port=9090
그다음 아래는 테스트는 안해봤는데 jdbctokenstore로 데이터베이스를 통해서 구현할 수 있다고 한다.
properties에서 datasource를 설정해주고
server.port=9090
spring.datasource.url=jdbc:mysql://localhost/spring?useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=
그리고나서 token store 를 resourceserver에서 구현해줌.
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.tokenStore(tokenStore());
}
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
}