resoucre 서버와 authorization 서버를 함께 구성하였음
주요 Dependencies
- lombok
- spring-boot-starter-security
- spring-security-oauth2
- spring-boot-starter-data-jpa
- spring-boot-starter-web
- mysql
프로젝트 구조
OauthApplication - 기본 springboot application
AuthorizationServiceConfigurerAdapterImpl - Authorizaion Server 구현
ResourceServerConfigurerAdapterImpl - Resourcet Server 구현
Member - 서비스할 객체
UserRepository - api service
Application 설정들
application.yml
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
|
#MYSQL
spring:
datasource:
url: jdbc:mysql://localhost:3306/study_db?autoReconnect=true&useSSL=false
driverClassName: com.mysql.jdbc.Driver
username: root
password: 1234
jpa:
show-sql: true
#security 설정
security:
user:
name: user
password: test
oauth2:
resource:
jwt:
key-uri: http://localhost:9093/oauth/token_key
client:
client-id: foo
client-secret: bar
authorization:
token-key-access: isAuthenticated()
#로깅레벨
logging:
level:
ROOT: error
#포트
server:
port: 9093
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
mysql 지정, spring security에서 client와 resoucre-owner정보 설정,
oauth의 토큰을 요청하는 url을 지정해주고(oauth/token_key는 기본값이다)
jwt 생성에 사용하는 키는 설정하지 않아 현재 자동으로 생성된다
API 구현
Member.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@Entity
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Member {
@Id
@GeneratedValue
private Long id;
private String name;
private String username;
private String remark;
@Builder
public Member(String name, String username, String remark) {
this.name = name;
this.username = username;
this.remark = remark;
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
jpa 형식으로 id, name, username, remark 필드를 갖는 Member 도메인 생성
@Id는 해당 프로퍼티가 테이블의 primary key 역할을 한다는것을 지정
@GeneratedVlaue는 id값을 DB의 identity 컬럼, 시퀀스, 테이블등을 이용하여 자동으로 생성해주도록 지정한다.
인자가없는 생성자를 private로 선언
MemberRepository.java
1
2
3
4
|
@RepositoryRestResource
public interface MemberRepository extends PagingAndSortingRepository<Member, Long> {}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
dependency에서 선언한 spring-data-rest에서 제공하는 기능으로
@RepositoryRestResource 어노테이션을 위와같은 방법으로 사용하는것 만으로
내부적으로 Rest API를 만들어 준다(여러종류의 요청을 생성)
여기까지의 구현만으로
localhost:{port}/members (전체 member조회)
localhost:{port}/members/2 (id가 2인 member조회)
등의 요청을 받아 응답할 수 있는 api서버가 만들어진다
ResourceServer 설정
ResourceServerConfigurerAdapterImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
|
@EnableResourceServer // 자원서버 설정
@Configuration
public class ResourceServerConfigurerAdapterImpl extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/members", "/members/**").access("#oauth2.hasScope('read')")
.anyRequest().authenticated();
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
localhost:{port}/members와 이후 url 요청시 권한을 가져야 가능하도록 하고(token이 있고, 해당 스코프를 가져야함)
AuthorizationServer 설정
AuthorizationServiceConfigurerAdapterImpl.java
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
|
@EnableAuthorizationServer
@Configuration
public class AuthorizationServiceConfigurerAdapterImpl extends OAuth2AuthorizationServerConfiguration{
private final JwtAccessTokenConverter jwtAccessTokenConverter;
public AuthorizationServiceConfigurerAdapterImpl(BaseClientDetails details,
AuthenticationManager authenticationManager, ObjectProvider<TokenStore> tokenStore,
ObjectProvider<AccessTokenConverter> tokenConverter, AuthorizationServerProperties properties) {
super(details, authenticationManager, tokenStore, tokenConverter, properties);
this.jwtAccessTokenConverter = new JwtAccessTokenConverter();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
super.configure(endpoints);
endpoints.accessTokenConverter(jwtAccessTokenConverter);
}
}
@Configuration
class OAuth2Configuration {
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
return new JwtAccessTokenConverter();
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
OAuth2AuthorizationServerConfiguration를 상속받아 AuthorizionServer를 구현한다
상속시 AuthorizationServiceConfigurerAdapterImpl 메소드를 구현해야 하는데 기본설정에
jwtAccessTokenConverter만 추가로 지정하였다
Oauth2Configuration에서는 토큰을 jwt로 사용하기위해
configuration을 추가하여 tokenstore와 Converter bean을 만들어줬다
테스트
1. api를 통해 조회할 자료 생성
지정해준 mysql에 member테이블을 만들고 조회할 값들을 미리 넣어준다(@Entity로 선언된 Member Class와연동)
2. access token 없이 조회
token이 없을시 MemberRepository를 이용해 구현한 api에 조회할 수 없다
3. access token 발급 후 조회
application.yml에 설정해둔 client_id, security의 기본 user, password등의 값을 이용해 토큰을 발급받는다
권한설정부분과 body에 필요한 파라미터를 설정후 /oauth/token url에 post로 요청하여 토큰을 발급받는다
발급받은 토큰을 확인해보자
jwt.io 사이트를 이용해 토큰을 Decode하여 확인 결과 정상적으로 발급되었음을 알수있다
발급된토큰을 포함하여 /members를 다시 요청해보면
정상적으로 조회하려던 api의 리턴을 받을 수 있다
해당프로젝트 소스 : https://github.com/m0oogi/oauth2_msa
'BackEnd > Spring, SpringBoot' 카테고리의 다른 글
[SpringBoot/Restful API] 1) Spring vs Springboot (0) | 2022.05.23 |
---|---|
[SpringBoot/JPA]웹 서비스 구현 - 1) 엔티티 (0) | 2021.04.30 |
[SpringBoot]Oauth2.0 jwt token (0) | 2019.12.25 |