1
1
/*
2
- * Copyright 2002-2017 the original author or authors.
2
+ * Copyright 2002-2018 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
15
15
*/
16
16
package org .springframework .security .oauth2 .client .userinfo ;
17
17
18
+ import org .springframework .core .convert .converter .Converter ;
19
+ import org .springframework .http .RequestEntity ;
20
+ import org .springframework .http .ResponseEntity ;
21
+ import org .springframework .security .oauth2 .client .http .OAuth2ErrorResponseErrorHandler ;
18
22
import org .springframework .security .oauth2 .client .registration .ClientRegistration ;
19
23
import org .springframework .security .oauth2 .core .OAuth2AuthenticationException ;
24
+ import org .springframework .security .oauth2 .core .OAuth2Error ;
20
25
import org .springframework .security .oauth2 .core .user .OAuth2User ;
21
26
import org .springframework .util .Assert ;
27
+ import org .springframework .web .client .ResponseErrorHandler ;
28
+ import org .springframework .web .client .RestClientException ;
29
+ import org .springframework .web .client .RestOperations ;
30
+ import org .springframework .web .client .RestTemplate ;
22
31
23
32
import java .util .Collections ;
24
33
import java .util .LinkedHashMap ;
39
48
* @see ClientRegistration
40
49
*/
41
50
public class CustomUserTypesOAuth2UserService implements OAuth2UserService <OAuth2UserRequest , OAuth2User > {
51
+ private static final String INVALID_USER_INFO_RESPONSE_ERROR_CODE = "invalid_user_info_response" ;
52
+
42
53
private final Map <String , Class <? extends OAuth2User >> customUserTypes ;
43
- private NimbusUserInfoResponseClient userInfoResponseClient = new NimbusUserInfoResponseClient ();
54
+
55
+ private Converter <OAuth2UserRequest , RequestEntity <?>> requestEntityConverter = new OAuth2UserRequestEntityConverter ();
56
+
57
+ private RestOperations restOperations ;
44
58
45
59
/**
46
60
* Constructs a {@code CustomUserTypesOAuth2UserService} using the provided parameters.
@@ -50,6 +64,9 @@ public class CustomUserTypesOAuth2UserService implements OAuth2UserService<OAuth
50
64
public CustomUserTypesOAuth2UserService (Map <String , Class <? extends OAuth2User >> customUserTypes ) {
51
65
Assert .notEmpty (customUserTypes , "customUserTypes cannot be empty" );
52
66
this .customUserTypes = Collections .unmodifiableMap (new LinkedHashMap <>(customUserTypes ));
67
+ RestTemplate restTemplate = new RestTemplate ();
68
+ restTemplate .setErrorHandler (new OAuth2ErrorResponseErrorHandler ());
69
+ this .restOperations = restTemplate ;
53
70
}
54
71
55
72
@ Override
@@ -60,6 +77,49 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
60
77
if ((customUserType = this .customUserTypes .get (registrationId )) == null ) {
61
78
return null ;
62
79
}
63
- return this .userInfoResponseClient .getUserInfoResponse (userRequest , customUserType );
80
+
81
+ RequestEntity <?> request = this .requestEntityConverter .convert (userRequest );
82
+
83
+ ResponseEntity <? extends OAuth2User > response ;
84
+ try {
85
+ response = this .restOperations .exchange (request , customUserType );
86
+ } catch (RestClientException ex ) {
87
+ OAuth2Error oauth2Error = new OAuth2Error (INVALID_USER_INFO_RESPONSE_ERROR_CODE ,
88
+ "An error occurred while attempting to retrieve the UserInfo Resource: " + ex .getMessage (), null );
89
+ throw new OAuth2AuthenticationException (oauth2Error , oauth2Error .toString (), ex );
90
+ }
91
+
92
+ OAuth2User oauth2User = response .getBody ();
93
+
94
+ return oauth2User ;
95
+ }
96
+
97
+ /**
98
+ * Sets the {@link Converter} used for converting the {@link OAuth2UserRequest}
99
+ * to a {@link RequestEntity} representation of the UserInfo Request.
100
+ *
101
+ * @since 5.1
102
+ * @param requestEntityConverter the {@link Converter} used for converting to a {@link RequestEntity} representation of the UserInfo Request
103
+ */
104
+ public final void setRequestEntityConverter (Converter <OAuth2UserRequest , RequestEntity <?>> requestEntityConverter ) {
105
+ Assert .notNull (requestEntityConverter , "requestEntityConverter cannot be null" );
106
+ this .requestEntityConverter = requestEntityConverter ;
107
+ }
108
+
109
+ /**
110
+ * Sets the {@link RestOperations} used when requesting the UserInfo resource.
111
+ *
112
+ * <p>
113
+ * <b>NOTE:</b> At a minimum, the supplied {@code restOperations} must be configured with the following:
114
+ * <ol>
115
+ * <li>{@link ResponseErrorHandler} - {@link OAuth2ErrorResponseErrorHandler}</li>
116
+ * </ol>
117
+ *
118
+ * @since 5.1
119
+ * @param restOperations the {@link RestOperations} used when requesting the UserInfo resource
120
+ */
121
+ public final void setRestOperations (RestOperations restOperations ) {
122
+ Assert .notNull (restOperations , "restOperations cannot be null" );
123
+ this .restOperations = restOperations ;
64
124
}
65
125
}
0 commit comments