1
1
/*
2
- * Copyright 2020 the original author or authors.
2
+ * Copyright 2020-2021 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 .core .oidc .http .converter ;
17
17
18
+ import java .time .Instant ;
19
+ import java .util .HashMap ;
20
+ import java .util .Map ;
21
+
18
22
import org .springframework .core .ParameterizedTypeReference ;
19
23
import org .springframework .core .convert .TypeDescriptor ;
20
24
import org .springframework .core .convert .converter .Converter ;
21
25
import org .springframework .http .HttpInputMessage ;
22
26
import org .springframework .http .HttpOutputMessage ;
23
27
import org .springframework .http .MediaType ;
24
- import org .springframework .http .converter .HttpMessageConverter ;
28
+ import org .springframework .http .converter .AbstractHttpMessageConverter ;
25
29
import org .springframework .http .converter .GenericHttpMessageConverter ;
26
- import org .springframework .http .converter .HttpMessageNotWritableException ;
30
+ import org .springframework .http .converter .HttpMessageConverter ;
27
31
import org .springframework .http .converter .HttpMessageNotReadableException ;
28
- import org .springframework .http .converter .AbstractHttpMessageConverter ;
32
+ import org .springframework .http .converter .HttpMessageNotWritableException ;
29
33
import org .springframework .security .oauth2 .core .converter .ClaimConversionService ;
30
34
import org .springframework .security .oauth2 .core .converter .ClaimTypeConverter ;
31
35
import org .springframework .security .oauth2 .core .oidc .OidcUserInfo ;
32
36
import org .springframework .security .oauth2 .core .oidc .StandardClaimNames ;
33
37
import org .springframework .util .Assert ;
34
38
35
- import java .util .HashMap ;
36
- import java .util .Map ;
37
-
38
39
/**
39
- * A {@link HttpMessageConverter} for an {@link OidcUserInfo OIDC User Info Response}.
40
+ * A {@link HttpMessageConverter} for an {@link OidcUserInfo OpenID Connect UserInfo Request and Response}.
40
41
*
41
42
* @author Ido Salomon
43
+ * @author Steve Riesenberg
44
+ * @since 0.2.1
42
45
* @see AbstractHttpMessageConverter
43
46
* @see OidcUserInfo
44
- * @since 0.1.1
45
47
*/
46
48
public class OidcUserInfoHttpMessageConverter extends AbstractHttpMessageConverter <OidcUserInfo > {
47
49
48
50
private static final ParameterizedTypeReference <Map <String , Object >> STRING_OBJECT_MAP =
49
- new ParameterizedTypeReference <Map <String , Object >>() {
50
- };
51
+ new ParameterizedTypeReference <Map <String , Object >>() {};
51
52
52
- private final GenericHttpMessageConverter <Object > jsonMessageConverter = HttpMessageConverters .getJsonMessageConverter ();
53
+ private final GenericHttpMessageConverter <Object > jsonMessageConverter =
54
+ HttpMessageConverters .getJsonMessageConverter ();
53
55
54
- private Converter <Map <String , Object >, OidcUserInfo > oidcUserInfoConverter = new OidcUserInfoConverter ();
55
- private Converter <OidcUserInfo , Map <String , Object >> oidcUserInfoParametersConverter = OidcUserInfo ::getClaims ;
56
+ private Converter <Map <String , Object >, OidcUserInfo > userInfoConverter = new MapOidcUserInfoConverter ();
57
+ private Converter <OidcUserInfo , Map <String , Object >> userInfoParametersConverter = OidcUserInfo ::getClaims ;
56
58
57
59
public OidcUserInfoHttpMessageConverter () {
58
60
super (MediaType .APPLICATION_JSON , new MediaType ("application" , "*+json" ));
@@ -68,90 +70,95 @@ protected boolean supports(Class<?> clazz) {
68
70
protected OidcUserInfo readInternal (Class <? extends OidcUserInfo > clazz , HttpInputMessage inputMessage )
69
71
throws HttpMessageNotReadableException {
70
72
try {
71
- Map <String , Object > oidcUserInfoParameters =
73
+ Map <String , Object > userInfoParameters =
72
74
(Map <String , Object >) this .jsonMessageConverter .read (STRING_OBJECT_MAP .getType (), null , inputMessage );
73
- return this .oidcUserInfoConverter .convert (oidcUserInfoParameters );
75
+ return this .userInfoConverter .convert (userInfoParameters );
74
76
} catch (Exception ex ) {
75
77
throw new HttpMessageNotReadableException (
76
- "An error occurred reading the OIDC User Info : " + ex .getMessage (), ex , inputMessage );
78
+ "An error occurred reading the UserInfo : " + ex .getMessage (), ex , inputMessage );
77
79
}
78
80
}
79
81
80
82
@ Override
81
83
protected void writeInternal (OidcUserInfo oidcUserInfo , HttpOutputMessage outputMessage )
82
84
throws HttpMessageNotWritableException {
83
85
try {
84
- Map <String , Object > oidcUserInfoResponseParameters =
85
- this .oidcUserInfoParametersConverter .convert (oidcUserInfo );
86
+ Map <String , Object > userInfoResponseParameters =
87
+ this .userInfoParametersConverter .convert (oidcUserInfo );
86
88
this .jsonMessageConverter .write (
87
- oidcUserInfoResponseParameters ,
89
+ userInfoResponseParameters ,
88
90
STRING_OBJECT_MAP .getType (),
89
91
MediaType .APPLICATION_JSON ,
90
92
outputMessage
91
93
);
92
94
} catch (Exception ex ) {
93
95
throw new HttpMessageNotWritableException (
94
- "An error occurred writing the OIDC User Info response: " + ex .getMessage (), ex );
96
+ "An error occurred writing the UserInfo response: " + ex .getMessage (), ex );
95
97
}
96
98
}
97
99
98
100
/**
99
- * Sets the {@link Converter} used for converting the OIDC User Info parameters
101
+ * Sets the {@link Converter} used for converting the UserInfo parameters
100
102
* to an {@link OidcUserInfo}.
101
103
*
102
- * @param oidcUserInfoConverter the {@link Converter} used for converting to an
103
- * {@link OidcUserInfo}
104
+ * @param userInfoConverter the {@link Converter} used for converting to an
105
+ * {@link OidcUserInfo}
104
106
*/
105
- public final void setOidcUserInfoConverter (Converter <Map <String , Object >, OidcUserInfo > oidcUserInfoConverter ) {
106
- Assert .notNull (oidcUserInfoConverter , "oidcUserInfoConverter cannot be null" );
107
- this .oidcUserInfoConverter = oidcUserInfoConverter ;
107
+ public final void setUserInfoConverter (Converter <Map <String , Object >, OidcUserInfo > userInfoConverter ) {
108
+ Assert .notNull (userInfoConverter , "userInfoConverter cannot be null" );
109
+ this .userInfoConverter = userInfoConverter ;
108
110
}
109
111
110
112
/**
111
113
* Sets the {@link Converter} used for converting the {@link OidcUserInfo} to a
112
- * {@code Map} representation of the OIDC User Info .
114
+ * {@code Map} representation of the UserInfo .
113
115
*
114
- * @param oidcUserInfoParametersConverter the {@link Converter} used for converting to a
115
- * {@code Map} representation of the OIDC User Info
116
+ * @param userInfoParametersConverter the {@link Converter} used for converting to a
117
+ * {@code Map} representation of the UserInfo
116
118
*/
117
- public final void setOidcUserInfoParametersConverter (
118
- Converter <OidcUserInfo , Map <String , Object >> oidcUserInfoParametersConverter ) {
119
- Assert .notNull (oidcUserInfoParametersConverter , "oidcUserInfoParametersConverter cannot be null" );
120
- this .oidcUserInfoParametersConverter = oidcUserInfoParametersConverter ;
119
+ public final void setUserInfoParametersConverter (
120
+ Converter <OidcUserInfo , Map <String , Object >> userInfoParametersConverter ) {
121
+ Assert .notNull (userInfoParametersConverter , "userInfoParametersConverter cannot be null" );
122
+ this .userInfoParametersConverter = userInfoParametersConverter ;
121
123
}
122
124
123
- private static final class OidcUserInfoConverter implements Converter <Map <String , Object >, OidcUserInfo > {
125
+ private static final class MapOidcUserInfoConverter implements Converter <Map <String , Object >, OidcUserInfo > {
126
+
124
127
private static final ClaimConversionService CLAIM_CONVERSION_SERVICE = ClaimConversionService .getSharedInstance ();
125
128
private static final TypeDescriptor OBJECT_TYPE_DESCRIPTOR = TypeDescriptor .valueOf (Object .class );
126
129
private static final TypeDescriptor BOOLEAN_TYPE_DESCRIPTOR = TypeDescriptor .valueOf (Boolean .class );
127
130
private static final TypeDescriptor STRING_TYPE_DESCRIPTOR = TypeDescriptor .valueOf (String .class );
131
+ private static final TypeDescriptor INSTANT_TYPE_DESCRIPTOR = TypeDescriptor .valueOf (Instant .class );
132
+ private static final TypeDescriptor STRING_OBJECT_MAP_DESCRIPTOR = TypeDescriptor .map (Map .class , STRING_TYPE_DESCRIPTOR , OBJECT_TYPE_DESCRIPTOR );
128
133
private final ClaimTypeConverter claimTypeConverter ;
129
134
130
- private OidcUserInfoConverter () {
131
- Converter <Object , ?> stringConverter = getConverter (STRING_TYPE_DESCRIPTOR );
135
+ private MapOidcUserInfoConverter () {
132
136
Converter <Object , ?> booleanConverter = getConverter (BOOLEAN_TYPE_DESCRIPTOR );
137
+ Converter <Object , ?> stringConverter = getConverter (STRING_TYPE_DESCRIPTOR );
138
+ Converter <Object , ?> instantConverter = getConverter (INSTANT_TYPE_DESCRIPTOR );
139
+ Converter <Object , ?> mapConverter = getConverter (STRING_OBJECT_MAP_DESCRIPTOR );
133
140
134
141
Map <String , Converter <Object , ?>> claimConverters = new HashMap <>();
135
142
claimConverters .put (StandardClaimNames .SUB , stringConverter );
136
- claimConverters .put (StandardClaimNames .PROFILE , stringConverter );
137
- claimConverters .put (StandardClaimNames .ADDRESS , stringConverter );
138
- claimConverters .put (StandardClaimNames .BIRTHDATE , stringConverter );
139
- claimConverters .put (StandardClaimNames .EMAIL , stringConverter );
140
- claimConverters .put (StandardClaimNames .EMAIL_VERIFIED , booleanConverter );
141
143
claimConverters .put (StandardClaimNames .NAME , stringConverter );
142
144
claimConverters .put (StandardClaimNames .GIVEN_NAME , stringConverter );
143
- claimConverters .put (StandardClaimNames .MIDDLE_NAME , stringConverter );
144
145
claimConverters .put (StandardClaimNames .FAMILY_NAME , stringConverter );
146
+ claimConverters .put (StandardClaimNames .MIDDLE_NAME , stringConverter );
145
147
claimConverters .put (StandardClaimNames .NICKNAME , stringConverter );
146
148
claimConverters .put (StandardClaimNames .PREFERRED_USERNAME , stringConverter );
147
- claimConverters .put (StandardClaimNames .LOCALE , stringConverter );
148
- claimConverters .put (StandardClaimNames .GENDER , stringConverter );
149
- claimConverters .put (StandardClaimNames .PHONE_NUMBER , stringConverter );
150
- claimConverters .put (StandardClaimNames .PHONE_NUMBER_VERIFIED , stringConverter );
149
+ claimConverters .put (StandardClaimNames .PROFILE , stringConverter );
151
150
claimConverters .put (StandardClaimNames .PICTURE , stringConverter );
152
- claimConverters .put (StandardClaimNames .ZONEINFO , stringConverter );
153
151
claimConverters .put (StandardClaimNames .WEBSITE , stringConverter );
154
- claimConverters .put (StandardClaimNames .UPDATED_AT , stringConverter );
152
+ claimConverters .put (StandardClaimNames .EMAIL , stringConverter );
153
+ claimConverters .put (StandardClaimNames .EMAIL_VERIFIED , booleanConverter );
154
+ claimConverters .put (StandardClaimNames .GENDER , stringConverter );
155
+ claimConverters .put (StandardClaimNames .BIRTHDATE , stringConverter );
156
+ claimConverters .put (StandardClaimNames .ZONEINFO , stringConverter );
157
+ claimConverters .put (StandardClaimNames .LOCALE , stringConverter );
158
+ claimConverters .put (StandardClaimNames .PHONE_NUMBER , stringConverter );
159
+ claimConverters .put (StandardClaimNames .PHONE_NUMBER_VERIFIED , booleanConverter );
160
+ claimConverters .put (StandardClaimNames .ADDRESS , mapConverter );
161
+ claimConverters .put (StandardClaimNames .UPDATED_AT , instantConverter );
155
162
156
163
this .claimTypeConverter = new ClaimTypeConverter (claimConverters );
157
164
}
0 commit comments