16
16
17
17
package org.springframework.security.config.annotation.web
18
18
19
+ import org.springframework.beans.factory.getBeanProvider
19
20
import org.springframework.context.ApplicationContext
21
+ import org.springframework.core.ResolvableType
20
22
import org.springframework.http.HttpMethod
21
23
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy
22
24
import org.springframework.security.access.hierarchicalroles.RoleHierarchy
23
- import org.springframework.security.authorization.AuthenticatedAuthorizationManager
24
- import org.springframework.security.authorization.AuthorityAuthorizationManager
25
- import org.springframework.security.authorization.AuthorizationDecision
26
25
import org.springframework.security.authorization.AuthorizationManager
26
+ import org.springframework.security.authorization.AuthorizationManagerFactory
27
+ import org.springframework.security.authorization.DefaultAuthorizationManagerFactory
27
28
import org.springframework.security.config.annotation.web.builders.HttpSecurity
28
29
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer
29
30
import org.springframework.security.config.core.GrantedAuthorityDefaults
30
- import org.springframework.security.core.Authentication
31
31
import org.springframework.security.web.access.IpAddressAuthorizationManager
32
32
import org.springframework.security.web.access.intercept.RequestAuthorizationContext
33
33
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
34
34
import org.springframework.security.web.util.matcher.AnyRequestMatcher
35
35
import org.springframework.security.web.util.matcher.RequestMatcher
36
- import java.util.function.Supplier
37
36
38
37
/* *
39
38
* A Kotlin DSL to configure [HttpSecurity] request authorization using idiomatic Kotlin code.
@@ -44,8 +43,7 @@ import java.util.function.Supplier
44
43
class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
45
44
46
45
private val authorizationRules = mutableListOf<AuthorizationManagerRule >()
47
- private val rolePrefix: String
48
- private val roleHierarchy: RoleHierarchy
46
+ private val authorizationManagerFactory: AuthorizationManagerFactory <in RequestAuthorizationContext >
49
47
50
48
private val PATTERN_TYPE = PatternType .PATH
51
49
@@ -57,7 +55,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
57
55
* (i.e. created via hasAuthority("ROLE_USER"))
58
56
*/
59
57
fun authorize (matches : RequestMatcher = AnyRequestMatcher .INSTANCE ,
60
- access : AuthorizationManager <RequestAuthorizationContext >) {
58
+ access : AuthorizationManager <in RequestAuthorizationContext >) {
61
59
authorizationRules.add(MatcherAuthorizationManagerRule (matches, access))
62
60
}
63
61
@@ -77,7 +75,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
77
75
* (i.e. created via hasAuthority("ROLE_USER"))
78
76
*/
79
77
fun authorize (pattern : String ,
80
- access : AuthorizationManager <RequestAuthorizationContext >) {
78
+ access : AuthorizationManager <in RequestAuthorizationContext >) {
81
79
authorizationRules.add(
82
80
PatternAuthorizationManagerRule (
83
81
pattern = pattern,
@@ -105,7 +103,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
105
103
*/
106
104
fun authorize (method : HttpMethod ,
107
105
pattern : String ,
108
- access : AuthorizationManager <RequestAuthorizationContext >) {
106
+ access : AuthorizationManager <in RequestAuthorizationContext >) {
109
107
authorizationRules.add(
110
108
PatternAuthorizationManagerRule (
111
109
pattern = pattern,
@@ -135,7 +133,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
135
133
*/
136
134
fun authorize (pattern : String ,
137
135
servletPath : String ,
138
- access : AuthorizationManager <RequestAuthorizationContext >) {
136
+ access : AuthorizationManager <in RequestAuthorizationContext >) {
139
137
authorizationRules.add(
140
138
PatternAuthorizationManagerRule (
141
139
pattern = pattern,
@@ -167,7 +165,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
167
165
fun authorize (method : HttpMethod ,
168
166
pattern : String ,
169
167
servletPath : String ,
170
- access : AuthorizationManager <RequestAuthorizationContext >) {
168
+ access : AuthorizationManager <in RequestAuthorizationContext >) {
171
169
authorizationRules.add(
172
170
PatternAuthorizationManagerRule (
173
171
pattern = pattern,
@@ -185,43 +183,48 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
185
183
* @param authority the authority to require (i.e. ROLE_USER, ROLE_ADMIN, etc).
186
184
* @return the [AuthorizationManager] with the provided authority
187
185
*/
188
- fun hasAuthority (authority : String ): AuthorizationManager <RequestAuthorizationContext > {
189
- val manager = AuthorityAuthorizationManager .hasAuthority<RequestAuthorizationContext >(authority)
190
- return withRoleHierarchy(manager)
191
- }
186
+ fun hasAuthority (authority : String ): AuthorizationManager <in RequestAuthorizationContext > = this .authorizationManagerFactory.hasAuthority(authority)
192
187
193
188
/* *
194
189
* Specify that URLs require any of the provided authorities.
195
190
*
196
191
* @param authorities the authorities to require (i.e. ROLE_USER, ROLE_ADMIN, etc).
197
192
* @return the [AuthorizationManager] with the provided authorities
198
193
*/
199
- fun hasAnyAuthority (vararg authorities : String ): AuthorizationManager <RequestAuthorizationContext > {
200
- val manager = AuthorityAuthorizationManager .hasAnyAuthority<RequestAuthorizationContext >(* authorities)
201
- return withRoleHierarchy(manager)
202
- }
194
+ fun hasAnyAuthority (vararg authorities : String ): AuthorizationManager <in RequestAuthorizationContext > = this .authorizationManagerFactory.hasAnyAuthority(* authorities)
195
+
196
+
197
+ /* *
198
+ * Specify that URLs require any of the provided authorities.
199
+ *
200
+ * @param authorities the authorities to require (i.e. ROLE_USER, ROLE_ADMIN, etc).
201
+ * @return the [AuthorizationManager] with the provided authorities
202
+ */
203
+ fun hasAllAuthorities (vararg authorities : String ): AuthorizationManager <in RequestAuthorizationContext > = this .authorizationManagerFactory.hasAllAuthorities(* authorities)
203
204
204
205
/* *
205
206
* Specify that URLs require a particular role.
206
207
*
207
208
* @param role the role to require (i.e. USER, ADMIN, etc).
208
209
* @return the [AuthorizationManager] with the provided role
209
210
*/
210
- fun hasRole (role : String ): AuthorizationManager <RequestAuthorizationContext > {
211
- val manager = AuthorityAuthorizationManager .hasAnyRole<RequestAuthorizationContext >(this .rolePrefix, arrayOf(role))
212
- return withRoleHierarchy(manager)
213
- }
211
+ fun hasRole (role : String ): AuthorizationManager <in RequestAuthorizationContext > = this .authorizationManagerFactory.hasRole(role)
214
212
215
213
/* *
216
214
* Specify that URLs require any of the provided roles.
217
215
*
218
216
* @param roles the roles to require (i.e. USER, ADMIN, etc).
219
217
* @return the [AuthorizationManager] with the provided roles
220
218
*/
221
- fun hasAnyRole (vararg roles : String ): AuthorizationManager <RequestAuthorizationContext > {
222
- val manager = AuthorityAuthorizationManager .hasAnyRole<RequestAuthorizationContext >(this .rolePrefix, arrayOf(* roles))
223
- return withRoleHierarchy(manager)
224
- }
219
+ fun hasAnyRole (vararg roles : String ): AuthorizationManager <in RequestAuthorizationContext > = this .authorizationManagerFactory.hasAnyRole(* roles)
220
+
221
+ /* *
222
+ * Specify that URLs require any of the provided roles.
223
+ *
224
+ * @param roles the roles to require (i.e. USER, ADMIN, etc).
225
+ * @return the [AuthorizationManager] with the provided roles
226
+ */
227
+ fun hasAllRoles (vararg roles : String ): AuthorizationManager <in RequestAuthorizationContext > = this .authorizationManagerFactory.hasAllRoles(* roles)
225
228
226
229
/* *
227
230
* Require a specific IP or range of IP addresses.
@@ -233,27 +236,23 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
233
236
/* *
234
237
* Specify that URLs are allowed by anyone.
235
238
*/
236
- val permitAll: AuthorizationManager <RequestAuthorizationContext > =
237
- AuthorizationManager { _: Supplier <out Authentication >, _: RequestAuthorizationContext -> AuthorizationDecision (true ) }
239
+ val permitAll: AuthorizationManager <in RequestAuthorizationContext >
238
240
239
241
/* *
240
242
* Specify that URLs are not allowed by anyone.
241
243
*/
242
- val denyAll: AuthorizationManager <RequestAuthorizationContext > =
243
- AuthorizationManager { _: Supplier <out Authentication >, _: RequestAuthorizationContext -> AuthorizationDecision (false ) }
244
+ val denyAll: AuthorizationManager <in RequestAuthorizationContext >
244
245
245
246
/* *
246
247
* Specify that URLs are allowed by any authenticated user.
247
248
*/
248
- val authenticated: AuthorizationManager <RequestAuthorizationContext > =
249
- AuthenticatedAuthorizationManager .authenticated()
249
+ val authenticated: AuthorizationManager <in RequestAuthorizationContext >
250
250
251
251
/* *
252
252
* Specify that URLs are allowed by users who have authenticated and were not "remembered".
253
253
* @since 6.5
254
254
*/
255
- val fullyAuthenticated: AuthorizationManager <RequestAuthorizationContext > =
256
- AuthenticatedAuthorizationManager .fullyAuthenticated()
255
+ val fullyAuthenticated: AuthorizationManager <in RequestAuthorizationContext >
257
256
258
257
internal fun get (): (AuthorizeHttpRequestsConfigurer <HttpSecurity >.AuthorizationManagerRequestMatcherRegistry ) -> Unit {
259
258
return { requests ->
@@ -274,16 +273,34 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
274
273
}
275
274
}
276
275
277
- constructor () {
278
- this .rolePrefix = " ROLE_"
279
- this .roleHierarchy = NullRoleHierarchy ()
276
+ constructor (context: ApplicationContext ) {
277
+ this .authorizationManagerFactory = resolveAuthorizationManagerFactory(context)
278
+ this .authenticated = this .authorizationManagerFactory.authenticated()
279
+ this .denyAll = this .authorizationManagerFactory.denyAll()
280
+ this .fullyAuthenticated = this .authorizationManagerFactory.fullyAuthenticated()
281
+ this .permitAll = this .authorizationManagerFactory.permitAll()
280
282
}
281
283
282
- constructor (context: ApplicationContext ) {
284
+ private fun resolveAuthorizationManagerFactory (context : ApplicationContext ): AuthorizationManagerFactory <in RequestAuthorizationContext > {
285
+ val specific = context.getBeanProvider<AuthorizationManagerFactory <RequestAuthorizationContext >>().getIfUnique()
286
+ if (specific != null ) {
287
+ return specific
288
+ }
289
+ val type = ResolvableType .forClassWithGenerics(AuthorizationManagerFactory ::class .java, Object ::class .java)
290
+ val general: AuthorizationManagerFactory <in RequestAuthorizationContext >? = context.getBeanProvider<AuthorizationManagerFactory <in RequestAuthorizationContext >>(type).getIfUnique()
291
+ if (general != null ) {
292
+ return general
293
+ }
294
+ val defaultFactory: DefaultAuthorizationManagerFactory <RequestAuthorizationContext > = DefaultAuthorizationManagerFactory ()
283
295
val rolePrefix = resolveRolePrefix(context)
284
- this .rolePrefix = rolePrefix
296
+ if (rolePrefix != null ) {
297
+ defaultFactory.setRolePrefix(rolePrefix)
298
+ }
285
299
val roleHierarchy = resolveRoleHierarchy(context)
286
- this .roleHierarchy = roleHierarchy
300
+ if (roleHierarchy != null ) {
301
+ defaultFactory.setRoleHierarchy(roleHierarchy)
302
+ }
303
+ return defaultFactory
287
304
}
288
305
289
306
private fun resolveRolePrefix (context : ApplicationContext ): String {
@@ -301,9 +318,4 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
301
318
}
302
319
return NullRoleHierarchy ()
303
320
}
304
-
305
- private fun withRoleHierarchy (manager : AuthorityAuthorizationManager <RequestAuthorizationContext >): AuthorityAuthorizationManager <RequestAuthorizationContext > {
306
- manager.setRoleHierarchy(this .roleHierarchy)
307
- return manager
308
- }
309
321
}
0 commit comments