15
15
*/
16
16
package org .springframework .security .oauth2 .core .authentication ;
17
17
18
+ import java .util .Collections ;
18
19
import java .util .HashMap ;
19
20
import java .util .Map ;
21
+ import java .util .function .Consumer ;
20
22
21
23
import org .springframework .lang .Nullable ;
22
24
import org .springframework .security .core .Authentication ;
25
27
import org .springframework .util .CollectionUtils ;
26
28
27
29
/**
28
- * A context that holds an {@link Authentication} and (optionally) additional information
29
- * and is used by an {@link OAuth2AuthenticationValidator} when attempting to validate the {@link Authentication}.
30
+ * A context that holds an {@link Authentication} and (optionally) additional information.
30
31
*
31
32
* @author Joe Grandja
32
33
* @since 0.2.0
33
34
* @see Context
34
- * @see OAuth2AuthenticationValidator
35
35
*/
36
- public final class OAuth2AuthenticationContext implements Context {
36
+ public class OAuth2AuthenticationContext implements Context {
37
37
private final Map <Object , Object > context ;
38
38
39
39
/**
40
40
* Constructs an {@code OAuth2AuthenticationContext} using the provided parameters.
41
41
*
42
42
* @param authentication the {@code Authentication}
43
43
* @param context a {@code Map} of additional context information
44
+ * @deprecated Use {@link #with(Authentication)} instead
44
45
*/
46
+ @ Deprecated
45
47
public OAuth2AuthenticationContext (Authentication authentication , @ Nullable Map <Object , Object > context ) {
46
48
Assert .notNull (authentication , "authentication cannot be null" );
47
- this . context = new HashMap <>();
49
+ Map < Object , Object > ctx = new HashMap <>();
48
50
if (!CollectionUtils .isEmpty (context )) {
49
- this . context .putAll (context );
51
+ ctx .putAll (context );
50
52
}
51
- this .context .put (Authentication .class , authentication );
53
+ ctx .put (Authentication .class , authentication );
54
+ this .context = Collections .unmodifiableMap (ctx );
55
+ }
56
+
57
+ protected OAuth2AuthenticationContext (Map <Object , Object > context ) {
58
+ Assert .notEmpty (context , "context cannot be empty" );
59
+ Assert .notNull (context .get (Authentication .class ), "authentication cannot be null" );
60
+ this .context = Collections .unmodifiableMap (new HashMap <>(context ));
52
61
}
53
62
54
63
/**
55
- * Returns the {@link Authentication} associated to the authentication context.
64
+ * Returns the {@link Authentication} associated to the context.
56
65
*
57
66
* @param <T> the type of the {@code Authentication}
58
67
* @return the {@link Authentication}
@@ -63,14 +72,105 @@ public <T extends Authentication> T getAuthentication() {
63
72
}
64
73
65
74
@ SuppressWarnings ("unchecked" )
75
+ @ Nullable
66
76
@ Override
67
77
public <V > V get (Object key ) {
68
- return ( V ) this .context .get (key );
78
+ return hasKey ( key ) ? ( V ) this .context .get (key ) : null ;
69
79
}
70
80
71
81
@ Override
72
82
public boolean hasKey (Object key ) {
83
+ Assert .notNull (key , "key cannot be null" );
73
84
return this .context .containsKey (key );
74
85
}
75
86
87
+ /**
88
+ * Constructs a new {@link Builder} with the provided {@link Authentication}.
89
+ *
90
+ * @param authentication the {@link Authentication}
91
+ * @return the {@link Builder}
92
+ */
93
+ public static Builder with (Authentication authentication ) {
94
+ return new Builder (authentication );
95
+ }
96
+
97
+ /**
98
+ * A builder for {@link OAuth2AuthenticationContext}.
99
+ */
100
+ public static final class Builder extends AbstractBuilder <OAuth2AuthenticationContext , Builder > {
101
+
102
+ private Builder (Authentication authentication ) {
103
+ super (authentication );
104
+ }
105
+
106
+ @ Override
107
+ public OAuth2AuthenticationContext build () {
108
+ return new OAuth2AuthenticationContext (getContext ());
109
+ }
110
+
111
+ }
112
+
113
+ /**
114
+ * A builder for subclasses of {@link OAuth2AuthenticationContext}.
115
+ *
116
+ * @param <T> the type of the authentication context
117
+ * @param <B> the type of the builder
118
+ */
119
+ protected static abstract class AbstractBuilder <T extends OAuth2AuthenticationContext , B extends AbstractBuilder <T , B >> {
120
+ private final Map <Object , Object > context = new HashMap <>();
121
+
122
+ protected AbstractBuilder (Authentication authentication ) {
123
+ Assert .notNull (authentication , "authentication cannot be null" );
124
+ put (Authentication .class , authentication );
125
+ }
126
+
127
+ /**
128
+ * Associates an attribute.
129
+ *
130
+ * @param key the key for the attribute
131
+ * @param value the value of the attribute
132
+ * @return the {@link AbstractBuilder} for further configuration
133
+ */
134
+ public B put (Object key , Object value ) {
135
+ Assert .notNull (key , "key cannot be null" );
136
+ Assert .notNull (value , "value cannot be null" );
137
+ getContext ().put (key , value );
138
+ return getThis ();
139
+ }
140
+
141
+ /**
142
+ * A {@code Consumer} of the attributes {@code Map}
143
+ * allowing the ability to add, replace, or remove.
144
+ *
145
+ * @param contextConsumer a {@link Consumer} of the attributes {@code Map}
146
+ * @return the {@link AbstractBuilder} for further configuration
147
+ */
148
+ public B context (Consumer <Map <Object , Object >> contextConsumer ) {
149
+ contextConsumer .accept (getContext ());
150
+ return getThis ();
151
+ }
152
+
153
+ @ SuppressWarnings ("unchecked" )
154
+ protected <V > V get (Object key ) {
155
+ return (V ) getContext ().get (key );
156
+ }
157
+
158
+ protected Map <Object , Object > getContext () {
159
+ return this .context ;
160
+ }
161
+
162
+ @ SuppressWarnings ("unchecked" )
163
+ protected final B getThis () {
164
+ return (B ) this ;
165
+ }
166
+
167
+ /**
168
+ * Builds a new {@link OAuth2AuthenticationContext}.
169
+ *
170
+ * @return the {@link OAuth2AuthenticationContext}
171
+ */
172
+ public abstract T build ();
173
+
174
+ }
175
+
76
176
}
0 commit comments