1616
1717package org.springframework.security.config.annotation.web
1818
19+ import org.springframework.beans.factory.getBeanProvider
1920import org.springframework.context.ApplicationContext
21+ import org.springframework.core.ResolvableType
2022import org.springframework.http.HttpMethod
2123import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy
2224import 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
2625import org.springframework.security.authorization.AuthorizationManager
26+ import org.springframework.security.authorization.AuthorizationManagerFactory
27+ import org.springframework.security.authorization.DefaultAuthorizationManagerFactory
2728import org.springframework.security.config.annotation.web.builders.HttpSecurity
2829import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer
2930import org.springframework.security.config.core.GrantedAuthorityDefaults
30- import org.springframework.security.core.Authentication
3131import org.springframework.security.web.access.IpAddressAuthorizationManager
3232import org.springframework.security.web.access.intercept.RequestAuthorizationContext
3333import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
3434import org.springframework.security.web.util.matcher.AnyRequestMatcher
3535import org.springframework.security.web.util.matcher.RequestMatcher
36- import java.util.function.Supplier
3736
3837/* *
3938 * A Kotlin DSL to configure [HttpSecurity] request authorization using idiomatic Kotlin code.
@@ -44,8 +43,7 @@ import java.util.function.Supplier
4443class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
4544
4645 private val authorizationRules = mutableListOf<AuthorizationManagerRule >()
47- private val rolePrefix: String
48- private val roleHierarchy: RoleHierarchy
46+ private val authorizationManagerFactory: AuthorizationManagerFactory <in RequestAuthorizationContext >
4947
5048 private val PATTERN_TYPE = PatternType .PATH
5149
@@ -57,7 +55,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
5755 * (i.e. created via hasAuthority("ROLE_USER"))
5856 */
5957 fun authorize (matches : RequestMatcher = AnyRequestMatcher .INSTANCE ,
60- access : AuthorizationManager <RequestAuthorizationContext >) {
58+ access : AuthorizationManager <in RequestAuthorizationContext >) {
6159 authorizationRules.add(MatcherAuthorizationManagerRule (matches, access))
6260 }
6361
@@ -77,7 +75,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
7775 * (i.e. created via hasAuthority("ROLE_USER"))
7876 */
7977 fun authorize (pattern : String ,
80- access : AuthorizationManager <RequestAuthorizationContext >) {
78+ access : AuthorizationManager <in RequestAuthorizationContext >) {
8179 authorizationRules.add(
8280 PatternAuthorizationManagerRule (
8381 pattern = pattern,
@@ -105,7 +103,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
105103 */
106104 fun authorize (method : HttpMethod ,
107105 pattern : String ,
108- access : AuthorizationManager <RequestAuthorizationContext >) {
106+ access : AuthorizationManager <in RequestAuthorizationContext >) {
109107 authorizationRules.add(
110108 PatternAuthorizationManagerRule (
111109 pattern = pattern,
@@ -135,7 +133,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
135133 */
136134 fun authorize (pattern : String ,
137135 servletPath : String ,
138- access : AuthorizationManager <RequestAuthorizationContext >) {
136+ access : AuthorizationManager <in RequestAuthorizationContext >) {
139137 authorizationRules.add(
140138 PatternAuthorizationManagerRule (
141139 pattern = pattern,
@@ -167,7 +165,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
167165 fun authorize (method : HttpMethod ,
168166 pattern : String ,
169167 servletPath : String ,
170- access : AuthorizationManager <RequestAuthorizationContext >) {
168+ access : AuthorizationManager <in RequestAuthorizationContext >) {
171169 authorizationRules.add(
172170 PatternAuthorizationManagerRule (
173171 pattern = pattern,
@@ -185,43 +183,48 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
185183 * @param authority the authority to require (i.e. ROLE_USER, ROLE_ADMIN, etc).
186184 * @return the [AuthorizationManager] with the provided authority
187185 */
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)
192187
193188 /* *
194189 * Specify that URLs require any of the provided authorities.
195190 *
196191 * @param authorities the authorities to require (i.e. ROLE_USER, ROLE_ADMIN, etc).
197192 * @return the [AuthorizationManager] with the provided authorities
198193 */
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)
203204
204205 /* *
205206 * Specify that URLs require a particular role.
206207 *
207208 * @param role the role to require (i.e. USER, ADMIN, etc).
208209 * @return the [AuthorizationManager] with the provided role
209210 */
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)
214212
215213 /* *
216214 * Specify that URLs require any of the provided roles.
217215 *
218216 * @param roles the roles to require (i.e. USER, ADMIN, etc).
219217 * @return the [AuthorizationManager] with the provided roles
220218 */
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)
225228
226229 /* *
227230 * Require a specific IP or range of IP addresses.
@@ -233,27 +236,23 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
233236 /* *
234237 * Specify that URLs are allowed by anyone.
235238 */
236- val permitAll: AuthorizationManager <RequestAuthorizationContext > =
237- AuthorizationManager { _: Supplier <out Authentication >, _: RequestAuthorizationContext -> AuthorizationDecision (true ) }
239+ val permitAll: AuthorizationManager <in RequestAuthorizationContext >
238240
239241 /* *
240242 * Specify that URLs are not allowed by anyone.
241243 */
242- val denyAll: AuthorizationManager <RequestAuthorizationContext > =
243- AuthorizationManager { _: Supplier <out Authentication >, _: RequestAuthorizationContext -> AuthorizationDecision (false ) }
244+ val denyAll: AuthorizationManager <in RequestAuthorizationContext >
244245
245246 /* *
246247 * Specify that URLs are allowed by any authenticated user.
247248 */
248- val authenticated: AuthorizationManager <RequestAuthorizationContext > =
249- AuthenticatedAuthorizationManager .authenticated()
249+ val authenticated: AuthorizationManager <in RequestAuthorizationContext >
250250
251251 /* *
252252 * Specify that URLs are allowed by users who have authenticated and were not "remembered".
253253 * @since 6.5
254254 */
255- val fullyAuthenticated: AuthorizationManager <RequestAuthorizationContext > =
256- AuthenticatedAuthorizationManager .fullyAuthenticated()
255+ val fullyAuthenticated: AuthorizationManager <in RequestAuthorizationContext >
257256
258257 internal fun get (): (AuthorizeHttpRequestsConfigurer <HttpSecurity >.AuthorizationManagerRequestMatcherRegistry ) -> Unit {
259258 return { requests ->
@@ -274,16 +273,34 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
274273 }
275274 }
276275
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()
280282 }
281283
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 ()
283295 val rolePrefix = resolveRolePrefix(context)
284- this .rolePrefix = rolePrefix
296+ if (rolePrefix != null ) {
297+ defaultFactory.setRolePrefix(rolePrefix)
298+ }
285299 val roleHierarchy = resolveRoleHierarchy(context)
286- this .roleHierarchy = roleHierarchy
300+ if (roleHierarchy != null ) {
301+ defaultFactory.setRoleHierarchy(roleHierarchy)
302+ }
303+ return defaultFactory
287304 }
288305
289306 private fun resolveRolePrefix (context : ApplicationContext ): String {
@@ -301,9 +318,4 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
301318 }
302319 return NullRoleHierarchy ()
303320 }
304-
305- private fun withRoleHierarchy (manager : AuthorityAuthorizationManager <RequestAuthorizationContext >): AuthorityAuthorizationManager <RequestAuthorizationContext > {
306- manager.setRoleHierarchy(this .roleHierarchy)
307- return manager
308- }
309321}
0 commit comments