|
|
|
@ -16,24 +16,23 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.security.config.annotation.web |
|
|
|
package org.springframework.security.config.annotation.web |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.factory.getBeanProvider |
|
|
|
import org.springframework.context.ApplicationContext |
|
|
|
import org.springframework.context.ApplicationContext |
|
|
|
|
|
|
|
import org.springframework.core.ResolvableType |
|
|
|
import org.springframework.http.HttpMethod |
|
|
|
import org.springframework.http.HttpMethod |
|
|
|
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy |
|
|
|
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy |
|
|
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy |
|
|
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy |
|
|
|
import org.springframework.security.authorization.AuthenticatedAuthorizationManager |
|
|
|
|
|
|
|
import org.springframework.security.authorization.AuthorityAuthorizationManager |
|
|
|
|
|
|
|
import org.springframework.security.authorization.AuthorizationDecision |
|
|
|
|
|
|
|
import org.springframework.security.authorization.AuthorizationManager |
|
|
|
import org.springframework.security.authorization.AuthorizationManager |
|
|
|
|
|
|
|
import org.springframework.security.authorization.AuthorizationManagerFactory |
|
|
|
|
|
|
|
import org.springframework.security.authorization.DefaultAuthorizationManagerFactory |
|
|
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity |
|
|
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity |
|
|
|
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer |
|
|
|
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer |
|
|
|
import org.springframework.security.config.core.GrantedAuthorityDefaults |
|
|
|
import org.springframework.security.config.core.GrantedAuthorityDefaults |
|
|
|
import org.springframework.security.core.Authentication |
|
|
|
|
|
|
|
import org.springframework.security.web.access.IpAddressAuthorizationManager |
|
|
|
import org.springframework.security.web.access.IpAddressAuthorizationManager |
|
|
|
import org.springframework.security.web.access.intercept.RequestAuthorizationContext |
|
|
|
import org.springframework.security.web.access.intercept.RequestAuthorizationContext |
|
|
|
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher |
|
|
|
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher |
|
|
|
import org.springframework.security.web.util.matcher.AnyRequestMatcher |
|
|
|
import org.springframework.security.web.util.matcher.AnyRequestMatcher |
|
|
|
import org.springframework.security.web.util.matcher.RequestMatcher |
|
|
|
import org.springframework.security.web.util.matcher.RequestMatcher |
|
|
|
import java.util.function.Supplier |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* A Kotlin DSL to configure [HttpSecurity] request authorization using idiomatic Kotlin code. |
|
|
|
* A Kotlin DSL to configure [HttpSecurity] request authorization using idiomatic Kotlin code. |
|
|
|
@ -44,8 +43,7 @@ import java.util.function.Supplier |
|
|
|
class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
|
|
|
|
|
|
|
|
private val authorizationRules = mutableListOf<AuthorizationManagerRule>() |
|
|
|
private val authorizationRules = mutableListOf<AuthorizationManagerRule>() |
|
|
|
private val rolePrefix: String |
|
|
|
private val authorizationManagerFactory: AuthorizationManagerFactory<in RequestAuthorizationContext> |
|
|
|
private val roleHierarchy: RoleHierarchy |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private val PATTERN_TYPE = PatternType.PATH |
|
|
|
private val PATTERN_TYPE = PatternType.PATH |
|
|
|
|
|
|
|
|
|
|
|
@ -57,7 +55,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
* (i.e. created via hasAuthority("ROLE_USER")) |
|
|
|
* (i.e. created via hasAuthority("ROLE_USER")) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun authorize(matches: RequestMatcher = AnyRequestMatcher.INSTANCE, |
|
|
|
fun authorize(matches: RequestMatcher = AnyRequestMatcher.INSTANCE, |
|
|
|
access: AuthorizationManager<RequestAuthorizationContext>) { |
|
|
|
access: AuthorizationManager<in RequestAuthorizationContext>) { |
|
|
|
authorizationRules.add(MatcherAuthorizationManagerRule(matches, access)) |
|
|
|
authorizationRules.add(MatcherAuthorizationManagerRule(matches, access)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -77,7 +75,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
* (i.e. created via hasAuthority("ROLE_USER")) |
|
|
|
* (i.e. created via hasAuthority("ROLE_USER")) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun authorize(pattern: String, |
|
|
|
fun authorize(pattern: String, |
|
|
|
access: AuthorizationManager<RequestAuthorizationContext>) { |
|
|
|
access: AuthorizationManager<in RequestAuthorizationContext>) { |
|
|
|
authorizationRules.add( |
|
|
|
authorizationRules.add( |
|
|
|
PatternAuthorizationManagerRule( |
|
|
|
PatternAuthorizationManagerRule( |
|
|
|
pattern = pattern, |
|
|
|
pattern = pattern, |
|
|
|
@ -105,7 +103,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun authorize(method: HttpMethod, |
|
|
|
fun authorize(method: HttpMethod, |
|
|
|
pattern: String, |
|
|
|
pattern: String, |
|
|
|
access: AuthorizationManager<RequestAuthorizationContext>) { |
|
|
|
access: AuthorizationManager<in RequestAuthorizationContext>) { |
|
|
|
authorizationRules.add( |
|
|
|
authorizationRules.add( |
|
|
|
PatternAuthorizationManagerRule( |
|
|
|
PatternAuthorizationManagerRule( |
|
|
|
pattern = pattern, |
|
|
|
pattern = pattern, |
|
|
|
@ -135,7 +133,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun authorize(pattern: String, |
|
|
|
fun authorize(pattern: String, |
|
|
|
servletPath: String, |
|
|
|
servletPath: String, |
|
|
|
access: AuthorizationManager<RequestAuthorizationContext>) { |
|
|
|
access: AuthorizationManager<in RequestAuthorizationContext>) { |
|
|
|
authorizationRules.add( |
|
|
|
authorizationRules.add( |
|
|
|
PatternAuthorizationManagerRule( |
|
|
|
PatternAuthorizationManagerRule( |
|
|
|
pattern = pattern, |
|
|
|
pattern = pattern, |
|
|
|
@ -167,7 +165,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
fun authorize(method: HttpMethod, |
|
|
|
fun authorize(method: HttpMethod, |
|
|
|
pattern: String, |
|
|
|
pattern: String, |
|
|
|
servletPath: String, |
|
|
|
servletPath: String, |
|
|
|
access: AuthorizationManager<RequestAuthorizationContext>) { |
|
|
|
access: AuthorizationManager<in RequestAuthorizationContext>) { |
|
|
|
authorizationRules.add( |
|
|
|
authorizationRules.add( |
|
|
|
PatternAuthorizationManagerRule( |
|
|
|
PatternAuthorizationManagerRule( |
|
|
|
pattern = pattern, |
|
|
|
pattern = pattern, |
|
|
|
@ -185,10 +183,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
* @param authority the authority to require (i.e. ROLE_USER, ROLE_ADMIN, etc). |
|
|
|
* @param authority the authority to require (i.e. ROLE_USER, ROLE_ADMIN, etc). |
|
|
|
* @return the [AuthorizationManager] with the provided authority |
|
|
|
* @return the [AuthorizationManager] with the provided authority |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun hasAuthority(authority: String): AuthorizationManager<RequestAuthorizationContext> { |
|
|
|
fun hasAuthority(authority: String): AuthorizationManager<in RequestAuthorizationContext> = this.authorizationManagerFactory.hasAuthority(authority) |
|
|
|
val manager = AuthorityAuthorizationManager.hasAuthority<RequestAuthorizationContext>(authority) |
|
|
|
|
|
|
|
return withRoleHierarchy(manager) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Specify that URLs require any of the provided authorities. |
|
|
|
* Specify that URLs require any of the provided authorities. |
|
|
|
@ -196,10 +191,16 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
* @param authorities the authorities to require (i.e. ROLE_USER, ROLE_ADMIN, etc). |
|
|
|
* @param authorities the authorities to require (i.e. ROLE_USER, ROLE_ADMIN, etc). |
|
|
|
* @return the [AuthorizationManager] with the provided authorities |
|
|
|
* @return the [AuthorizationManager] with the provided authorities |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun hasAnyAuthority(vararg authorities: String): AuthorizationManager<RequestAuthorizationContext> { |
|
|
|
fun hasAnyAuthority(vararg authorities: String): AuthorizationManager<in RequestAuthorizationContext> = this.authorizationManagerFactory.hasAnyAuthority(*authorities) |
|
|
|
val manager = AuthorityAuthorizationManager.hasAnyAuthority<RequestAuthorizationContext>(*authorities) |
|
|
|
|
|
|
|
return withRoleHierarchy(manager) |
|
|
|
|
|
|
|
} |
|
|
|
/** |
|
|
|
|
|
|
|
* Specify that URLs require any of the provided authorities. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param authorities the authorities to require (i.e. ROLE_USER, ROLE_ADMIN, etc). |
|
|
|
|
|
|
|
* @return the [AuthorizationManager] with the provided authorities |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
fun hasAllAuthorities(vararg authorities: String): AuthorizationManager<in RequestAuthorizationContext> = this.authorizationManagerFactory.hasAllAuthorities(*authorities) |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Specify that URLs require a particular role. |
|
|
|
* Specify that URLs require a particular role. |
|
|
|
@ -207,10 +208,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
* @param role the role to require (i.e. USER, ADMIN, etc). |
|
|
|
* @param role the role to require (i.e. USER, ADMIN, etc). |
|
|
|
* @return the [AuthorizationManager] with the provided role |
|
|
|
* @return the [AuthorizationManager] with the provided role |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun hasRole(role: String): AuthorizationManager<RequestAuthorizationContext> { |
|
|
|
fun hasRole(role: String): AuthorizationManager<in RequestAuthorizationContext> = this.authorizationManagerFactory.hasRole(role) |
|
|
|
val manager = AuthorityAuthorizationManager.hasAnyRole<RequestAuthorizationContext>(this.rolePrefix, arrayOf(role)) |
|
|
|
|
|
|
|
return withRoleHierarchy(manager) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Specify that URLs require any of the provided roles. |
|
|
|
* Specify that URLs require any of the provided roles. |
|
|
|
@ -218,10 +216,15 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
* @param roles the roles to require (i.e. USER, ADMIN, etc). |
|
|
|
* @param roles the roles to require (i.e. USER, ADMIN, etc). |
|
|
|
* @return the [AuthorizationManager] with the provided roles |
|
|
|
* @return the [AuthorizationManager] with the provided roles |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun hasAnyRole(vararg roles: String): AuthorizationManager<RequestAuthorizationContext> { |
|
|
|
fun hasAnyRole(vararg roles: String): AuthorizationManager<in RequestAuthorizationContext> = this.authorizationManagerFactory.hasAnyRole(*roles) |
|
|
|
val manager = AuthorityAuthorizationManager.hasAnyRole<RequestAuthorizationContext>(this.rolePrefix, arrayOf(*roles)) |
|
|
|
|
|
|
|
return withRoleHierarchy(manager) |
|
|
|
/** |
|
|
|
} |
|
|
|
* Specify that URLs require any of the provided roles. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param roles the roles to require (i.e. USER, ADMIN, etc). |
|
|
|
|
|
|
|
* @return the [AuthorizationManager] with the provided roles |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
fun hasAllRoles(vararg roles: String): AuthorizationManager<in RequestAuthorizationContext> = this.authorizationManagerFactory.hasAllRoles(*roles) |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Require a specific IP or range of IP addresses. |
|
|
|
* Require a specific IP or range of IP addresses. |
|
|
|
@ -233,27 +236,23 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Specify that URLs are allowed by anyone. |
|
|
|
* Specify that URLs are allowed by anyone. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
val permitAll: AuthorizationManager<RequestAuthorizationContext> = |
|
|
|
val permitAll: AuthorizationManager<in RequestAuthorizationContext> |
|
|
|
AuthorizationManager { _: Supplier<out Authentication>, _: RequestAuthorizationContext -> AuthorizationDecision(true) } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Specify that URLs are not allowed by anyone. |
|
|
|
* Specify that URLs are not allowed by anyone. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
val denyAll: AuthorizationManager<RequestAuthorizationContext> = |
|
|
|
val denyAll: AuthorizationManager<in RequestAuthorizationContext> |
|
|
|
AuthorizationManager { _: Supplier<out Authentication>, _: RequestAuthorizationContext -> AuthorizationDecision(false) } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Specify that URLs are allowed by any authenticated user. |
|
|
|
* Specify that URLs are allowed by any authenticated user. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
val authenticated: AuthorizationManager<RequestAuthorizationContext> = |
|
|
|
val authenticated: AuthorizationManager<in RequestAuthorizationContext> |
|
|
|
AuthenticatedAuthorizationManager.authenticated() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Specify that URLs are allowed by users who have authenticated and were not "remembered". |
|
|
|
* Specify that URLs are allowed by users who have authenticated and were not "remembered". |
|
|
|
* @since 6.5 |
|
|
|
* @since 6.5 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
val fullyAuthenticated: AuthorizationManager<RequestAuthorizationContext> = |
|
|
|
val fullyAuthenticated: AuthorizationManager<in RequestAuthorizationContext> |
|
|
|
AuthenticatedAuthorizationManager.fullyAuthenticated() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal fun get(): (AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry) -> Unit { |
|
|
|
internal fun get(): (AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry) -> Unit { |
|
|
|
return { requests -> |
|
|
|
return { requests -> |
|
|
|
@ -274,16 +273,34 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constructor() { |
|
|
|
constructor(context: ApplicationContext) { |
|
|
|
this.rolePrefix = "ROLE_" |
|
|
|
this.authorizationManagerFactory = resolveAuthorizationManagerFactory(context) |
|
|
|
this.roleHierarchy = NullRoleHierarchy() |
|
|
|
this.authenticated = this.authorizationManagerFactory.authenticated() |
|
|
|
|
|
|
|
this.denyAll = this.authorizationManagerFactory.denyAll() |
|
|
|
|
|
|
|
this.fullyAuthenticated = this.authorizationManagerFactory.fullyAuthenticated() |
|
|
|
|
|
|
|
this.permitAll = this.authorizationManagerFactory.permitAll() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constructor(context: ApplicationContext) { |
|
|
|
private fun resolveAuthorizationManagerFactory(context: ApplicationContext): AuthorizationManagerFactory<in RequestAuthorizationContext> { |
|
|
|
|
|
|
|
val specific = context.getBeanProvider<AuthorizationManagerFactory<RequestAuthorizationContext>>().getIfUnique() |
|
|
|
|
|
|
|
if (specific != null) { |
|
|
|
|
|
|
|
return specific |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
val type = ResolvableType.forClassWithGenerics(AuthorizationManagerFactory::class.java, Object::class.java) |
|
|
|
|
|
|
|
val general: AuthorizationManagerFactory<in RequestAuthorizationContext>? = context.getBeanProvider<AuthorizationManagerFactory<in RequestAuthorizationContext>>(type).getIfUnique() |
|
|
|
|
|
|
|
if (general != null) { |
|
|
|
|
|
|
|
return general |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
val defaultFactory: DefaultAuthorizationManagerFactory<RequestAuthorizationContext> = DefaultAuthorizationManagerFactory() |
|
|
|
val rolePrefix = resolveRolePrefix(context) |
|
|
|
val rolePrefix = resolveRolePrefix(context) |
|
|
|
this.rolePrefix = rolePrefix |
|
|
|
if (rolePrefix != null) { |
|
|
|
|
|
|
|
defaultFactory.setRolePrefix(rolePrefix) |
|
|
|
|
|
|
|
} |
|
|
|
val roleHierarchy = resolveRoleHierarchy(context) |
|
|
|
val roleHierarchy = resolveRoleHierarchy(context) |
|
|
|
this.roleHierarchy = roleHierarchy |
|
|
|
if (roleHierarchy != null) { |
|
|
|
|
|
|
|
defaultFactory.setRoleHierarchy(roleHierarchy) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return defaultFactory |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun resolveRolePrefix(context: ApplicationContext): String { |
|
|
|
private fun resolveRolePrefix(context: ApplicationContext): String { |
|
|
|
@ -301,9 +318,4 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { |
|
|
|
} |
|
|
|
} |
|
|
|
return NullRoleHierarchy() |
|
|
|
return NullRoleHierarchy() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun withRoleHierarchy(manager: AuthorityAuthorizationManager<RequestAuthorizationContext>): AuthorityAuthorizationManager<RequestAuthorizationContext> { |
|
|
|
|
|
|
|
manager.setRoleHierarchy(this.roleHierarchy) |
|
|
|
|
|
|
|
return manager |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|