#oauth2 方法级别的安全表达式
#oauth2 security expressions on method level
我应该怎么做才能像下面的示例那样在方法级别使用#oauth2 安全表达式?
@RequestMapping(value = "email", method = RequestMethod.GET)
@ResponseBody
@PreAuthorize("#oauth2.hasScope('read')")
public String email() {
return "test@email.com";
}
如果我对该资源发出请求,我会收到
[INFO] java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.hasScope('read')'
[INFO] at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:14)
[INFO] at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:44)
[INFO] at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:57)
[INFO] at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:25)
[INFO] at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:62)
[INFO] at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232)
[INFO] at org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor.invoke(AspectJMethodSecurityInterceptor.java:43)
[INFO] at org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect.ajc$around$org_springframework_security_access_intercept_aspectj_aspect_AnnotationSecurityAspect$c4d57a2b(AnnotationSecurityAspect.aj:63)
[INFO] at pl.insert.controllers.ResourceController.email(ResourceController.java:22)
如果我在我的 ResourceServerConfiguration 中指定访问权限而不是@Controllers 的方法
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/oauth/resources/**");
http.authorizeRequests().anyRequest().access("#oauth2.hasScope('read')");
}
}
@PreAuthorize("permitAll") 或@PreAuthorize("denyAll") 等标准安全表达式按预期工作。所以,可能我必须以某种方式告诉我的 AspectJMethodSecurityInterceptor 使用 OAuth2WebSecurityExpressionHandler。有任何想法吗?
要启用#oAuth2 安全表达式,只需将默认表达式处理程序设置为 OAuth2MethodSecurityExpressionHandler 而不是 DefaultMethodSecurityExpressionHandler。因为 OAuth2MethodSecurityExpressionHandler 扩展了它,所以之前的所有功能都保持不变。在我的配置中,我同时使用了 GlobalMethodSecurityConfiguration 和 WebSecurityConfigurerAdapter。
@Configuration
@EnableGlobalMethodSecurity
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}
@Configuration
@Import({ SecurityConfiguration.class, MethodSecurityConfiguration.class })
public class AppConfiguration {
...
}
我想你还需要补充:
@EnableGlobalMethodSecurity(prePostEnabled = true) 为了让它工作。
我有同样的问题,但只是在单元测试中 (@WebMvcTest
)。我必须在定义测试配置的内部 class 上添加 @EnableGlobalMethodSecurity
:
@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
public class MyControllerTest {
@TestConfiguration
@Import({JacksonCustomizations.class,SecuritySettings.class,
OAuth2ServerConfiguration.class, WebSecurityConfiguration.class,
TokenGrantersConfiguration.class})
@EnableGlobalMethodSecurity
public static class TestConfig {
}
}
更新:在 Spring 引导 2.x 中,您可能会得到:
java.lang.IllegalStateException: In the composition of all global method configuration, no annotation support was actually activated
原因是您添加了 @EnableGlobalMethodSecurity
而没有实际启用任何东西。要修复它,请将注释的至少一个属性设置为 true。例如:
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
一个更简单的解决方案是让 Spring 引导自动配置。添加以下依赖项为我解决了这个问题:
compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.4.RELEASE')
对我来说,是
的组合
// spring configuration class annotation
@EnableGlobalMethodSecurity(prePostEnabled = true)
和
// gradle dependencuy
compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.4.RELEASE')
这是一个老问题,情况有所改变。对于 Spring Security 5,应该使用:
.hasAuthority("SCOPE_scopename")
Spring 根据从提供商那里收到的范围向主体添加权限,前缀为“SCOPE_”。
更多信息:https://www.baeldung.com/spring-security-openid-connect
我应该怎么做才能像下面的示例那样在方法级别使用#oauth2 安全表达式?
@RequestMapping(value = "email", method = RequestMethod.GET)
@ResponseBody
@PreAuthorize("#oauth2.hasScope('read')")
public String email() {
return "test@email.com";
}
如果我对该资源发出请求,我会收到
[INFO] java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.hasScope('read')'
[INFO] at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:14)
[INFO] at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:44)
[INFO] at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:57)
[INFO] at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:25)
[INFO] at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:62)
[INFO] at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232)
[INFO] at org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor.invoke(AspectJMethodSecurityInterceptor.java:43)
[INFO] at org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect.ajc$around$org_springframework_security_access_intercept_aspectj_aspect_AnnotationSecurityAspect$c4d57a2b(AnnotationSecurityAspect.aj:63)
[INFO] at pl.insert.controllers.ResourceController.email(ResourceController.java:22)
如果我在我的 ResourceServerConfiguration 中指定访问权限而不是@Controllers 的方法
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/oauth/resources/**");
http.authorizeRequests().anyRequest().access("#oauth2.hasScope('read')");
}
}
@PreAuthorize("permitAll") 或@PreAuthorize("denyAll") 等标准安全表达式按预期工作。所以,可能我必须以某种方式告诉我的 AspectJMethodSecurityInterceptor 使用 OAuth2WebSecurityExpressionHandler。有任何想法吗?
要启用#oAuth2 安全表达式,只需将默认表达式处理程序设置为 OAuth2MethodSecurityExpressionHandler 而不是 DefaultMethodSecurityExpressionHandler。因为 OAuth2MethodSecurityExpressionHandler 扩展了它,所以之前的所有功能都保持不变。在我的配置中,我同时使用了 GlobalMethodSecurityConfiguration 和 WebSecurityConfigurerAdapter。
@Configuration
@EnableGlobalMethodSecurity
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}
@Configuration
@Import({ SecurityConfiguration.class, MethodSecurityConfiguration.class })
public class AppConfiguration {
...
}
我想你还需要补充: @EnableGlobalMethodSecurity(prePostEnabled = true) 为了让它工作。
我有同样的问题,但只是在单元测试中 (@WebMvcTest
)。我必须在定义测试配置的内部 class 上添加 @EnableGlobalMethodSecurity
:
@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
public class MyControllerTest {
@TestConfiguration
@Import({JacksonCustomizations.class,SecuritySettings.class,
OAuth2ServerConfiguration.class, WebSecurityConfiguration.class,
TokenGrantersConfiguration.class})
@EnableGlobalMethodSecurity
public static class TestConfig {
}
}
更新:在 Spring 引导 2.x 中,您可能会得到:
java.lang.IllegalStateException: In the composition of all global method configuration, no annotation support was actually activated
原因是您添加了 @EnableGlobalMethodSecurity
而没有实际启用任何东西。要修复它,请将注释的至少一个属性设置为 true。例如:
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
一个更简单的解决方案是让 Spring 引导自动配置。添加以下依赖项为我解决了这个问题:
compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.4.RELEASE')
对我来说,是
// spring configuration class annotation
@EnableGlobalMethodSecurity(prePostEnabled = true)
和
// gradle dependencuy
compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.4.RELEASE')
这是一个老问题,情况有所改变。对于 Spring Security 5,应该使用:
.hasAuthority("SCOPE_scopename")
Spring 根据从提供商那里收到的范围向主体添加权限,前缀为“SCOPE_”。
更多信息:https://www.baeldung.com/spring-security-openid-connect