Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java #方法级别上的oauth2安全表达式_Java_Spring Mvc_Spring Security_Oauth 2.0 - Fatal编程技术网

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

Java #方法级别上的oauth2安全表达式,java,spring-mvc,spring-security,oauth-2.0,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"; } 如果我向收到的资源发出请求 [INFO] java.

我应该怎么做才能在方法级别上使用#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$1$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对其进行了扩展,所以之前的所有功能都保持不变。我在配置中同时使用GlobalMethodSecurity配置和WebSecurity配置适配器

@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 {
  ...
}

我认为你还需要补充: @启用GlobalMethodSecurity(prespenabled=true)以使其正常工作


我也有同样的问题,但只是在单元测试中(
@WebMvcTest
)。我必须在定义测试配置的内部类上添加
@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 Boot 2.x中,您可能会得到:

java.lang.IllegalStateException:在所有全局方法配置的组合中,实际上没有激活任何注释支持

原因是您添加了
@EnableGlobalMethodSecurity
,但实际上没有启用任何功能。若要修复此问题,请将注释的至少一个属性设置为true。例如:

@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)

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

compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.4.RELEASE')

对我来说,这是两者的结合


这是一个老问题,事情已经改变了。使用Spring Security 5时,应使用:

.hasAuthority("SCOPE_scopename")
Spring根据从提供者收到的作用域向主体添加权限,前缀为“作用域”


更多信息:

Hi@Marek!您找到问题的解决方案了吗?这里也有相同的问题……不幸的是,没有,据我记忆所及,我花了一些时间来解决这个问题,但解决方案太复杂了,最终不值得实施。我使用@Configuration手动执行此操作:(就我而言,这并不那么痛苦,但我可以想象,在某些情况下可能会如此。好的,谢谢你的回答。我只是在这里提出了一个问题:@Sébastienusbaumer检查下面的答案。我刚刚通过解决一个不同的问题找到了解决方案。它对我来说很好。我也有同样的问题。尝试过这个,但没有帮助。有人能帮我吗e请共享一些源代码?它是什么意思“它没有帮助”?是否已加载@Configuration类并创建ExpressionHandler()方法是否被调用过?如果“是”,请检查调试器AspectJMethodSecurityInterceptor是否真的使用了OAuth2MethodSecurityExpressionHandler。如果“否”,请调查原因。将覆盖添加到
createExpressionHandler
对我来说很好。其他解决方案声称您可以添加
spring-security-oauth2-autoconfigure
依赖项对我不起作用(至少在我的单元测试中没有,没有检查我的应用程序本身)。我必须删除与GlobalMethodSecurityConfiguration类相关的配置,我添加了这个依赖项,然后它就起作用了。
// gradle dependencuy
compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.4.RELEASE')
.hasAuthority("SCOPE_scopename")