Browse Source
Issue gh-18013 Signed-off-by: Josh Cummings <3627351+jzheaux@users.noreply.github.com>pull/18713/head
10 changed files with 258 additions and 0 deletions
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
package org.springframework.security.docs.servlet.oauth2.resourceserver.methodsecurityhasscope; |
||||
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
@Service |
||||
class MessageService { |
||||
|
||||
// tag::protected-method[]
|
||||
@PreAuthorize("@oauth2.hasScope('message:read')") |
||||
String readMessage() { |
||||
return "message"; |
||||
} |
||||
// end::protected-method[]
|
||||
} |
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
package org.springframework.security.docs.servlet.oauth2.resourceserver.methodsecurityhasscope; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; |
||||
import org.springframework.security.oauth2.core.authorization.DefaultOAuth2AuthorizationManagerFactory; |
||||
import org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagerFactory; |
||||
|
||||
@Configuration |
||||
@EnableMethodSecurity |
||||
class MethodSecurityHasScopeConfiguration { |
||||
// tag::declare-factory[]
|
||||
@Bean |
||||
OAuth2AuthorizationManagerFactory<?> oauth2() { |
||||
return new DefaultOAuth2AuthorizationManagerFactory<>(); |
||||
} |
||||
// end::declare-factory[]
|
||||
} |
||||
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
package org.springframework.security.docs.servlet.oauth2.resourceserver.methodsecurityhasscope; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.security.access.AccessDeniedException; |
||||
import org.springframework.security.config.test.SpringTestContext; |
||||
import org.springframework.security.config.test.SpringTestContextExtension; |
||||
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners; |
||||
import org.springframework.security.test.context.support.WithMockUser; |
||||
import org.springframework.test.context.junit.jupiter.SpringExtension; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
||||
|
||||
@ExtendWith(SpringTestContextExtension.class) |
||||
@ExtendWith(SpringExtension.class) |
||||
@SecurityTestExecutionListeners |
||||
public class MethodSecurityHasScopeConfigurationTests { |
||||
public final SpringTestContext spring = new SpringTestContext(this).mockMvcAfterSpringSecurityOk(); |
||||
|
||||
@Autowired |
||||
private MessageService messages; |
||||
|
||||
@Test |
||||
@WithMockUser(authorities = "SCOPE_message:read") |
||||
void readMessageWhenMessageReadThenAllowed() { |
||||
this.spring.register(MethodSecurityHasScopeConfiguration.class, MessageService.class).autowire(); |
||||
this.messages.readMessage(); |
||||
} |
||||
|
||||
@Test |
||||
@WithMockUser |
||||
void readMessageWhenNoScopeThenDenied() { |
||||
this.spring.register(MethodSecurityHasScopeConfiguration.class, MessageService.class).autowire(); |
||||
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.messages::readMessage); |
||||
} |
||||
|
||||
@Test |
||||
@WithMockUser(authorities = { "SCOPE_message:read", "FACTOR_BEARER", "FACTOR_X509" }) |
||||
void mfaReadMessageWhenMessageReadAndFactorsThenAllowed() { |
||||
this.spring.register(MethodSecurityHasScopeMfaConfiguration.class, MessageService.class).autowire(); |
||||
this.messages.readMessage(); |
||||
} |
||||
|
||||
@Test |
||||
@WithMockUser(authorities = { "SCOPE_message:read" }) |
||||
void mfaReadMessageWhenMessageReadThenDenied() { |
||||
this.spring.register(MethodSecurityHasScopeMfaConfiguration.class, MessageService.class).autowire(); |
||||
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.messages::readMessage); |
||||
} |
||||
|
||||
@Test |
||||
@WithMockUser |
||||
void mfaReadMessageWhenNoScopeThenDenied() { |
||||
this.spring.register(MethodSecurityHasScopeMfaConfiguration.class, MessageService.class).autowire(); |
||||
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.messages::readMessage); |
||||
} |
||||
} |
||||
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
package org.springframework.security.docs.servlet.oauth2.resourceserver.methodsecurityhasscope; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.security.authorization.AuthorizationManagerFactory; |
||||
import org.springframework.security.config.annotation.authorization.EnableMultiFactorAuthentication; |
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; |
||||
import org.springframework.security.oauth2.core.authorization.DefaultOAuth2AuthorizationManagerFactory; |
||||
import org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagerFactory; |
||||
|
||||
@Configuration |
||||
@EnableMethodSecurity |
||||
@EnableMultiFactorAuthentication(authorities = { "FACTOR_BEARER", "FACTOR_X509" }) |
||||
class MethodSecurityHasScopeMfaConfiguration { |
||||
// tag::declare-factory[]
|
||||
@Bean |
||||
OAuth2AuthorizationManagerFactory<?> oauth2(AuthorizationManagerFactory<?> authz) { |
||||
return new DefaultOAuth2AuthorizationManagerFactory<>(authz); |
||||
} |
||||
// end::declare-factory[]
|
||||
} |
||||
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
package org.springframework.security.kt.docs.servlet.oauth2.resourceserver.methodsecurityhasscope |
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize |
||||
import org.springframework.stereotype.Service |
||||
|
||||
|
||||
@Service |
||||
open class MessageService { |
||||
// tag::protected-method[] |
||||
@PreAuthorize("@oauth2.hasScope('message:read')") |
||||
open fun readMessage(): String { |
||||
return "message" |
||||
} |
||||
// end::protected-method[] |
||||
} |
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
package org.springframework.security.kt.docs.servlet.oauth2.resourceserver.methodsecurityhasscope |
||||
|
||||
import org.springframework.context.annotation.Bean |
||||
import org.springframework.context.annotation.Configuration |
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity |
||||
import org.springframework.security.oauth2.core.authorization.DefaultOAuth2AuthorizationManagerFactory |
||||
import org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagerFactory |
||||
|
||||
@Configuration |
||||
@EnableMethodSecurity |
||||
open class MethodSecurityHasScopeConfiguration { |
||||
// tag::declare-factory[] |
||||
@Bean |
||||
open fun oauth2(): OAuth2AuthorizationManagerFactory<Any> { |
||||
return DefaultOAuth2AuthorizationManagerFactory() |
||||
} |
||||
// end::declare-factory[] |
||||
} |
||||
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
package org.springframework.security.kt.docs.servlet.oauth2.resourceserver.methodsecurityhasscope |
||||
|
||||
import org.assertj.core.api.Assertions |
||||
import org.junit.jupiter.api.Test |
||||
import org.junit.jupiter.api.extension.ExtendWith |
||||
import org.springframework.beans.factory.annotation.Autowired |
||||
import org.springframework.security.access.AccessDeniedException |
||||
import org.springframework.security.config.test.SpringTestContext |
||||
import org.springframework.security.config.test.SpringTestContextExtension |
||||
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners |
||||
import org.springframework.security.test.context.support.WithMockUser |
||||
import org.springframework.test.context.junit.jupiter.SpringExtension |
||||
|
||||
@ExtendWith(SpringTestContextExtension::class) |
||||
@ExtendWith(SpringExtension::class) |
||||
@SecurityTestExecutionListeners |
||||
class MethodSecurityHasScopeConfigurationTests { |
||||
@JvmField |
||||
val spring: SpringTestContext = SpringTestContext(this).mockMvcAfterSpringSecurityOk() |
||||
|
||||
@Autowired |
||||
var messages: MessageService? = null |
||||
|
||||
@Test |
||||
@WithMockUser(authorities = ["SCOPE_message:read"]) |
||||
fun readMessageWhenMessageReadThenAllowed() { |
||||
this.spring.register(MethodSecurityHasScopeConfiguration::class.java, MessageService::class.java).autowire() |
||||
this.messages!!.readMessage() |
||||
} |
||||
|
||||
@Test |
||||
@WithMockUser |
||||
fun readMessageWhenNoScopeThenDenied() { |
||||
this.spring.register(MethodSecurityHasScopeConfiguration::class.java, MessageService::class.java).autowire() |
||||
Assertions.assertThatExceptionOfType<AccessDeniedException?>(AccessDeniedException::class.java) |
||||
.isThrownBy({ this.messages!!.readMessage() }) |
||||
} |
||||
|
||||
@Test |
||||
@WithMockUser(authorities = ["SCOPE_message:read", "FACTOR_BEARER", "FACTOR_X509"]) |
||||
fun mfaReadMessageWhenMessageReadAndFactorsThenAllowed() { |
||||
this.spring.register(MethodSecurityHasScopeMfaConfiguration::class.java, MessageService::class.java).autowire() |
||||
this.messages!!.readMessage() |
||||
} |
||||
|
||||
@Test |
||||
@WithMockUser(authorities = ["SCOPE_message:read"]) |
||||
fun mfaReadMessageWhenMessageReadThenDenied() { |
||||
this.spring.register(MethodSecurityHasScopeMfaConfiguration::class.java, MessageService::class.java).autowire() |
||||
Assertions.assertThatExceptionOfType<AccessDeniedException?>(AccessDeniedException::class.java) |
||||
.isThrownBy({ this.messages!!.readMessage() }) |
||||
} |
||||
|
||||
@Test |
||||
@WithMockUser |
||||
fun mfaReadMessageWhenNoScopeThenDenied() { |
||||
this.spring.register(MethodSecurityHasScopeMfaConfiguration::class.java, MessageService::class.java).autowire() |
||||
Assertions.assertThatExceptionOfType<AccessDeniedException?>(AccessDeniedException::class.java) |
||||
.isThrownBy({ this.messages!!.readMessage() }) |
||||
} |
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
package org.springframework.security.kt.docs.servlet.oauth2.resourceserver.methodsecurityhasscope |
||||
|
||||
import org.springframework.context.annotation.Bean |
||||
import org.springframework.context.annotation.Configuration |
||||
import org.springframework.security.authorization.AuthorizationManagerFactory |
||||
import org.springframework.security.config.annotation.authorization.EnableMultiFactorAuthentication |
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity |
||||
import org.springframework.security.oauth2.core.authorization.DefaultOAuth2AuthorizationManagerFactory |
||||
import org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagerFactory |
||||
|
||||
@Configuration |
||||
@EnableMethodSecurity |
||||
@EnableMultiFactorAuthentication(authorities = ["FACTOR_BEARER", "FACTOR_X509"]) |
||||
open class MethodSecurityHasScopeMfaConfiguration { |
||||
// tag::declare-factory[] |
||||
@Bean |
||||
open fun oauth2(authz: AuthorizationManagerFactory<Any>): OAuth2AuthorizationManagerFactory<Any> { |
||||
return DefaultOAuth2AuthorizationManagerFactory(authz) |
||||
} // end::declare-factory[] |
||||
} |
||||
Loading…
Reference in new issue