From 2fb3d3d5a2ce1b15829fd36a77db0ab8e34b5b2a Mon Sep 17 00:00:00 2001 From: Eleftheria Stein Date: Tue, 25 Feb 2020 08:29:26 -0500 Subject: [PATCH] Add hasRole to authorizeRequests in Kotlin DSL Fixes: gh-8023 --- .../web/servlet/AuthorizeRequestsDsl.kt | 9 +++ .../web/servlet/AuthorizeRequestsDslTests.kt | 63 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/config/src/main/kotlin/org/springframework/security/config/web/servlet/AuthorizeRequestsDsl.kt b/config/src/main/kotlin/org/springframework/security/config/web/servlet/AuthorizeRequestsDsl.kt index a8b42aae50..5734c2caf6 100644 --- a/config/src/main/kotlin/org/springframework/security/config/web/servlet/AuthorizeRequestsDsl.kt +++ b/config/src/main/kotlin/org/springframework/security/config/web/servlet/AuthorizeRequestsDsl.kt @@ -105,6 +105,15 @@ class AuthorizeRequestsDsl : AbstractRequestMatcherDsl() { */ fun hasAuthority(authority: String) = "hasAuthority('$authority')" + /** + * Specify that URLs require a particular role. + * + * @param role the role to require (i.e. USER, ADMIN, etc). + * @return the SpEL expression "hasRole" with the given role as a + * parameter + */ + fun hasRole(role: String) = "hasRole('$role')" + /** * Specify that URLs are allowed by anyone. */ diff --git a/config/src/test/kotlin/org/springframework/security/config/web/servlet/AuthorizeRequestsDslTests.kt b/config/src/test/kotlin/org/springframework/security/config/web/servlet/AuthorizeRequestsDslTests.kt index e1471d4a0c..c4508ba8b3 100644 --- a/config/src/test/kotlin/org/springframework/security/config/web/servlet/AuthorizeRequestsDslTests.kt +++ b/config/src/test/kotlin/org/springframework/security/config/web/servlet/AuthorizeRequestsDslTests.kt @@ -19,15 +19,21 @@ package org.springframework.security.config.web.servlet import org.junit.Rule import org.junit.Test import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Bean import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter import org.springframework.security.config.test.SpringTestRule +import org.springframework.security.core.userdetails.User +import org.springframework.security.core.userdetails.UserDetailsService +import org.springframework.security.provisioning.InMemoryUserDetailsManager +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic import org.springframework.security.web.util.matcher.RegexRequestMatcher import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.get import org.springframework.test.web.servlet.request.MockMvcRequestBuilders import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @@ -169,6 +175,63 @@ class AuthorizeRequestsDslTests { } } + @Test + fun `request when user has allowed role then responds with OK`() { + this.spring.register(HasRoleConfig::class.java).autowire() + + this.mockMvc.get("/") { + with(httpBasic("admin", "password")) + }.andExpect { + status { isOk } + } + } + + @Test + fun `request when user does not have allowed role then responds with forbidden`() { + this.spring.register(HasRoleConfig::class.java).autowire() + + this.mockMvc.get("/") { + with(httpBasic("user", "password")) + }.andExpect { + status { isForbidden } + } + } + + @EnableWebSecurity + @EnableWebMvc + open class HasRoleConfig : WebSecurityConfigurerAdapter() { + override fun configure(http: HttpSecurity) { + http { + authorizeRequests { + authorize("/**", hasRole("ADMIN")) + } + httpBasic { } + } + } + + @RestController + internal class PathController { + @GetMapping("/") + fun index() { + } + } + + @Bean + override fun userDetailsService(): UserDetailsService { + val userDetails = User.withDefaultPasswordEncoder() + .username("user") + .password("password") + .roles("USER") + .build() + val adminDetails = User.withDefaultPasswordEncoder() + .username("admin") + .password("password") + .roles("ADMIN") + .build() + return InMemoryUserDetailsManager(userDetails, adminDetails) + } + } + @Test fun `request when secured by mvc with servlet path then responds based on servlet path`() { this.spring.register(MvcMatcherServletPathConfig::class.java).autowire()