IT

spring security in action chap.14

프로개발러 2023. 9. 11. 14:11
반응형

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);
    }
}
반응형