Oauth2

https://www.devglan.com/spring-security/spring-boot-security-oauth2-example 를 참고하세요!

Oauth1 ROLES

  1. oAuth Provider (ex : google, facebook, kakao, etc..)
  2. oAuth Client ( Using provider )
  3. Owner ( 실제 사용자)

OAuth2 Roles

  1. Resource Owner : user
  2. Client : Appication
  3. Resource Server : API
  4. Authoriztion Server : API

OAuth2 Grant Types

핸드쉐이킹 하는 방법이 4가지!

  1. Authorization Code: used with server-side Applications

  2. Implicit: used with Mobile Apps or Web Applications (applications that run on the user’s device)

  3. Resource Owner Password Credentials: used with trusted Applications, such as those owned by the service itself

  4. Client Credentials: used with Applications API access

Auth Server 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

static final String CLIEN_ID = "beanbroker-client";
static final String CLIENT_SECRET = "beanbroker-secret";
static final String PASS_WORD = "password";
static final String AUTHORIZATION_CODE = "authorization_code";
static final String REFRESH_TOKEN = "refresh_token";
static final String IMPLICIT = "implicit";
static final String SCOPE_READ = "read";
static final String SCOPE_WRITE = "write";
static final String TRUST = "trust";
static final int ACCESS_TOKEN_VALIDITY_SECONDS = 1*60*60;
static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 6*60*60;

private final TokenStore tokenStore;

private final AuthenticationManager authenticationManager;

private final PasswordEncoder passwordEncoder;

@Autowired
public AuthorizationServerConfig(TokenStore tokenStore, AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder) {
this.tokenStore = tokenStore;
this.authenticationManager = authenticationManager;
this.passwordEncoder = passwordEncoder;
}

@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {

configurer
.inMemory()
.withClient(CLIEN_ID)
// .secret(CLIENT_SECRET)
.secret(passwordEncoder.encode(CLIENT_SECRET))
.authorizedGrantTypes(PASS_WORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT )
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS).
refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS);
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
}
}
  1. TokenStore -> 토큰 저장하는 저장소

  2. AuthenticationManager -> 실질적인 인증 인터페이스이며, 인증 처리를 담당한다.

  3. grantType 4가지
  4. 토큰 만료기간 한시간
  5. 리프레시 토큰 만료기간 6시간
  6. client와 clientId -> 토큰을 받아오려면 클라이언트로 인증이 되어야만 받을수 있다

Resource Server Config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

private static final String RESOURCE_ID = "resource_id";

@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}

@Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.authorizeRequests()
.antMatchers("/users/**").authenticated()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}

}
  1. stateless

    • true : 토큰 인증만 할거면 true,
    • false : 아니면 false,
  2. authorizeRequests -> 유저에 접근하는 모든 request는 인증이 되어야함

깃헙 클론

깃헙을 클론하여 진행하여주세요. 그 외 다른 유저 서비스 및 정보들은 누구나 쉽게 구현하여 진행이 가능합니다

깃헙 주소

https://github.com/beanbroker/sample_oauth

테스트

postman으로 진행 postman impot

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
{
"info": {
"_postman_id": "1760d7bd-196d-40b3-90ba-ea05eded8d37",
"name": "study_oauth",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Get Token",
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "password",
"value": "beanbroker-secret",
"type": "string"
},
{
"key": "username",
"value": "beanbroker-client",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/x-www-form-urlencoded",
"type": "text"
}
],
"body": {
"mode": "urlencoded",
"urlencoded": [
{
"key": "username",
"value": "beanbroker",
"type": "text"
},
{
"key": "password",
"value": "12342",
"type": "text"
},
{
"key": "grant_type",
"value": "password",
"type": "text"
}
]
},
"url": {
"raw": "localhost:8080/oauth/token",
"host": [
"localhost"
],
"port": "8080",
"path": [
"oauth",
"token"
]
}
},
"response": []
},
{
"name": "Get User Info",
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"auth": {
"type": "oauth2",
"oauth2": [
{
"key": "accessToken",
"value": "f420e4db-d76f-49b8-bcd1-480d03832c4b",
"type": "string"
},
{
"key": "addTokenTo",
"value": "header",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/x-www-form-urlencoded",
"type": "text"
}
],
"body": {
"mode": "urlencoded",
"urlencoded": [
{
"key": "username",
"value": "beanbroker",
"type": "text"
},
{
"key": "password",
"value": "1234",
"type": "text"
},
{
"key": "grant_type",
"value": "password",
"type": "text"
}
]
},
"url": {
"raw": "localhost:8080/users/user",
"host": [
"localhost"
],
"port": "8080",
"path": [
"users",
"user"
]
}
},
"response": []
}
]
}

Get Token

localhost:8080/oauth/token

1
2
3
4
5
6
7
{
"access_token": "f420e4db-d76f-49b8-bcd1-480d03832c4b",
"token_type": "bearer",
"refresh_token": "f7216eeb-d1ba-4c93-832d-9b0ffa52e2db",
"expires_in": 3599,
"scope": "read write trust"
}

위와같이 토큰 발급이 진행되어진다.

정상적인 비밀번호를 입력하지 않을경우

1
2
3
4
{
"error": "invalid_grant",
"error_description": "Bad credentials"
}

Get User Info

localhost:8080/users/user

발급받은 access_token설정하여 request

1
2
3
4
5
6
7
[
{
"id": 1,
"userName": "beanbroker",
"password": "{bcrypt}$2a$10$UNtRqoEj2OoaD1trDP61hOxhZvPQISYd6Bz8px0wAn56LzHq5iO0."
}
]

유저정보 반환