#oauth2方法级别的安全表达式

Mar*_*ski 12 java spring-mvc spring-security oauth-2.0

如何在方法级别上使用#oauth2安全表达式,如下例所示,我该怎么办?

@RequestMapping(value = "email", method = RequestMethod.GET)
  @ResponseBody
  @PreAuthorize("#oauth2.hasScope('read')")
  public String email() {

    return "test@email.com";
  }
Run Code Online (Sandbox Code Playgroud)

如果我对我收到的资源提出请求

    [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$1$c4d57a2b(AnnotationSecurityAspect.aj:63)
[INFO]  at pl.insert.controllers.ResourceController.email(ResourceController.java:22)
Run Code Online (Sandbox Code Playgroud)

如果我在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')");
  }
}
Run Code Online (Sandbox Code Playgroud)

标准安全表达式(如@PreAuthorize("permitAll")或@PreAuthorize("denyAll")按预期工作.所以,我可能不得不告诉我的AspectJMethodSecurityInterceptor使用OAuth2WebSecurityExpressionHandler.有任何想法吗?

Mar*_*ski 13

要启用#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 {
  ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这是什么意思'它没有帮助'?是否已加载@Configuration类并且调用了createExpressionHandler()方法?如果'是',请在调试器中检查AspectJMethodSecurityInterceptor是否真的使用OAuth2MethodSecurityExpressionHandler.如果'不'调查原因. (2认同)

小智 5

我认为您还需要添加:@EnableGlobalMethodSecurity( prePostEnabled = true ) 才能使其正常工作。

在不同的页面上回答


Joh*_*anB 5

一个更简单的解决方案是让 Spring Boot 自动配置。添加以下依赖项为我解决了这个问题:

compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.4.RELEASE')
Run Code Online (Sandbox Code Playgroud)