13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*/
16
-
17
16
package org .springframework .security .config .annotation .web .configurers .oauth2 .server .authorization ;
18
17
19
- import java .time .Instant ;
20
-
21
18
import org .junit .Before ;
22
19
import org .junit .BeforeClass ;
23
20
import org .junit .Rule ;
24
21
import org .junit .Test ;
25
-
26
22
import org .springframework .beans .factory .annotation .Autowired ;
27
23
import org .springframework .context .annotation .Bean ;
28
24
import org .springframework .context .annotation .Import ;
25
+ import org .springframework .http .HttpHeaders ;
29
26
import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
30
27
import org .springframework .security .config .annotation .web .configuration .OAuth2AuthorizationServerConfiguration ;
31
28
import org .springframework .security .config .test .SpringTestRule ;
32
29
import org .springframework .security .crypto .keys .KeyManager ;
33
30
import org .springframework .security .crypto .keys .StaticKeyGeneratingKeyManager ;
34
31
import org .springframework .security .oauth2 .core .AuthorizationGrantType ;
35
- import org .springframework .security .oauth2 .core .OAuth2AccessToken ;
36
- import org .springframework .security .oauth2 .core .OAuth2RefreshToken ;
37
32
import org .springframework .security .oauth2 .core .endpoint .OAuth2ParameterNames ;
38
33
import org .springframework .security .oauth2 .server .authorization .OAuth2Authorization ;
39
34
import org .springframework .security .oauth2 .server .authorization .OAuth2AuthorizationService ;
42
37
import org .springframework .security .oauth2 .server .authorization .client .RegisteredClient ;
43
38
import org .springframework .security .oauth2 .server .authorization .client .RegisteredClientRepository ;
44
39
import org .springframework .security .oauth2 .server .authorization .client .TestRegisteredClients ;
45
- import org .springframework .security .oauth2 .server .authorization .token .OAuth2Tokens ;
46
40
import org .springframework .security .oauth2 .server .authorization .web .OAuth2TokenEndpointFilter ;
47
41
import org .springframework .test .web .servlet .MockMvc ;
42
+ import org .springframework .util .LinkedMultiValueMap ;
43
+ import org .springframework .util .MultiValueMap ;
48
44
45
+ import java .net .URLEncoder ;
46
+ import java .nio .charset .StandardCharsets ;
47
+ import java .util .Base64 ;
48
+
49
+ import static org .hamcrest .CoreMatchers .containsString ;
50
+ import static org .mockito .ArgumentMatchers .any ;
49
51
import static org .mockito .ArgumentMatchers .eq ;
50
52
import static org .mockito .Mockito .mock ;
51
53
import static org .mockito .Mockito .reset ;
54
+ import static org .mockito .Mockito .verify ;
52
55
import static org .mockito .Mockito .when ;
53
- import static org .springframework .security .test .web .servlet .request .SecurityMockMvcRequestPostProcessors .httpBasic ;
54
56
import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .post ;
57
+ import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .header ;
55
58
import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .jsonPath ;
56
59
import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .status ;
57
60
58
61
/**
62
+ * Integration tests for the OAuth 2.0 Refresh Token Grant.
63
+ *
59
64
* @author Alexey Nesterov
60
65
* @since 0.0.3
61
66
*/
62
67
public class OAuth2RefreshTokenGrantTests {
63
-
64
- private static final String TEST_REFRESH_TOKEN = "test-refresh-token" ;
65
-
66
68
private static RegisteredClientRepository registeredClientRepository ;
67
69
private static OAuth2AuthorizationService authorizationService ;
68
70
@@ -72,8 +74,6 @@ public class OAuth2RefreshTokenGrantTests {
72
74
@ Autowired
73
75
private MockMvc mvc ;
74
76
75
- private RegisteredClient registeredClient ;
76
-
77
77
@ BeforeClass
78
78
public static void init () {
79
79
registeredClientRepository = mock (RegisteredClientRepository .class );
@@ -84,33 +84,56 @@ public static void init() {
84
84
public void setup () {
85
85
reset (registeredClientRepository );
86
86
reset (authorizationService );
87
-
88
- this .registeredClient = TestRegisteredClients .registeredClient2 ().build ();
89
-
90
- this .spring .register (OAuth2RefreshTokenGrantTests .AuthorizationServerConfiguration .class ).autowire ();
91
87
}
92
88
93
89
@ Test
94
- public void requestWhenRefreshTokenExists () throws Exception {
95
- when (registeredClientRepository .findByClientId (eq (this .registeredClient .getClientId ())))
96
- .thenReturn (this .registeredClient );
97
-
98
- OAuth2Authorization authorization = TestOAuth2Authorizations .authorization (this .registeredClient )
99
- .tokens (OAuth2Tokens .builder ()
100
- .refreshToken (new OAuth2RefreshToken (TEST_REFRESH_TOKEN , Instant .now (), Instant .now ().plusSeconds (60 )))
101
- .accessToken (new OAuth2AccessToken (OAuth2AccessToken .TokenType .BEARER , "access-token" , Instant .now (), Instant .now ().plusSeconds (10 )))
102
- .build ())
103
- .build ();
104
-
105
- when (authorizationService .findByToken (TEST_REFRESH_TOKEN , TokenType .REFRESH_TOKEN ))
90
+ public void requestWhenRefreshTokenRequestValidThenReturnAccessTokenResponse () throws Exception {
91
+ this .spring .register (AuthorizationServerConfiguration .class ).autowire ();
92
+
93
+ RegisteredClient registeredClient = TestRegisteredClients .registeredClient ().build ();
94
+ when (registeredClientRepository .findByClientId (eq (registeredClient .getClientId ())))
95
+ .thenReturn (registeredClient );
96
+
97
+ OAuth2Authorization authorization = TestOAuth2Authorizations .authorization (registeredClient ).build ();
98
+ when (authorizationService .findByToken (
99
+ eq (authorization .getTokens ().getRefreshToken ().getTokenValue ()),
100
+ eq (TokenType .REFRESH_TOKEN )))
106
101
.thenReturn (authorization );
107
102
108
103
this .mvc .perform (post (OAuth2TokenEndpointFilter .DEFAULT_TOKEN_ENDPOINT_URI )
109
- .param ( OAuth2ParameterNames . GRANT_TYPE , AuthorizationGrantType . REFRESH_TOKEN . getValue ( ))
110
- .param ( OAuth2ParameterNames . REFRESH_TOKEN , TEST_REFRESH_TOKEN )
111
- . with ( httpBasic ( this . registeredClient .getClientId (), this . registeredClient .getClientSecret ())))
104
+ .params ( getRefreshTokenRequestParameters ( authorization ))
105
+ .header ( HttpHeaders . AUTHORIZATION , "Basic " + encodeBasicAuth (
106
+ registeredClient .getClientId (), registeredClient .getClientSecret ())))
112
107
.andExpect (status ().isOk ())
113
- .andExpect (jsonPath ("$.access_token" ).isNotEmpty ());
108
+ .andExpect (header ().string (HttpHeaders .CACHE_CONTROL , containsString ("no-store" )))
109
+ .andExpect (header ().string (HttpHeaders .PRAGMA , containsString ("no-cache" )))
110
+ .andExpect (jsonPath ("$.access_token" ).isNotEmpty ())
111
+ .andExpect (jsonPath ("$.token_type" ).isNotEmpty ())
112
+ .andExpect (jsonPath ("$.expires_in" ).isNotEmpty ())
113
+ .andExpect (jsonPath ("$.refresh_token" ).isNotEmpty ())
114
+ .andExpect (jsonPath ("$.scope" ).isNotEmpty ());
115
+
116
+ verify (registeredClientRepository ).findByClientId (eq (registeredClient .getClientId ()));
117
+ verify (authorizationService ).findByToken (
118
+ eq (authorization .getTokens ().getRefreshToken ().getTokenValue ()),
119
+ eq (TokenType .REFRESH_TOKEN ));
120
+ verify (authorizationService ).save (any ());
121
+
122
+ }
123
+
124
+ private static MultiValueMap <String , String > getRefreshTokenRequestParameters (OAuth2Authorization authorization ) {
125
+ MultiValueMap <String , String > parameters = new LinkedMultiValueMap <>();
126
+ parameters .set (OAuth2ParameterNames .GRANT_TYPE , AuthorizationGrantType .REFRESH_TOKEN .getValue ());
127
+ parameters .set (OAuth2ParameterNames .REFRESH_TOKEN , authorization .getTokens ().getRefreshToken ().getTokenValue ());
128
+ return parameters ;
129
+ }
130
+
131
+ private static String encodeBasicAuth (String clientId , String secret ) throws Exception {
132
+ clientId = URLEncoder .encode (clientId , StandardCharsets .UTF_8 .name ());
133
+ secret = URLEncoder .encode (secret , StandardCharsets .UTF_8 .name ());
134
+ String credentialsString = clientId + ":" + secret ;
135
+ byte [] encodedBytes = Base64 .getEncoder ().encode (credentialsString .getBytes (StandardCharsets .UTF_8 ));
136
+ return new String (encodedBytes , StandardCharsets .UTF_8 );
114
137
}
115
138
116
139
@ EnableWebSecurity
0 commit comments