Spring安全检查用户是否可以访问提到的url

时间:2017-07-24 09:19:00

标签: java spring spring-mvc spring-security

我已经开始使用spring security,经过大量研究后我无法找到答案:

如果我明确要检查用户A是否可以访问东西B.我可以使用JSP标记支持Spring Security - check if web url is secure / protected来检查这个

<sec:authorize url="stuff/B">

但是,如果我想在控制器(java类)中检查相同的内容,该怎么办?我在这里找不到任何弹簧函数来检查登录用户是否可以访问提到的URL(https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html

6 个答案:

答案 0 :(得分:14)

来自javadoc

的提示
  

要使用此标记,您的应用程序上下文中还必须有WebInvocationPrivilegeEvaluator的实例。如果您使用命名空间,将自动注册。这是DefaultWebInvocationPrivilegeEvaluator,“

的一个实例

DefaultWebInvocationPrivilegeEvaluator的javadoc中,我们可以看到应该执行此工作的isAllowed方法:

// privilegeEvaluator is a WebInvocationPrivilegeEvaluator "autowired"
boolean allowed = privilegeEvaluator.isAllowed("/stuff/B", yourAuthentication);

答案 1 :(得分:0)

为什么不使用这样的注释:

@PreAuthorize("hasRole('ROLE_USER')")
public void create(Contact contact);

注释是Spring 3 +的标准方法

答案 2 :(得分:0)

您正在寻找合适的地方,您附上的链接会提到您需要的内容。由于您需要在控制器上进行访问控制并按用户(而非角色)进行检查,因此您可以使用&#39; @ PreAuthorize&#39;带有&#34; hasPermission&#34;的注释表达或类似。

您可以检查here基于表达式的访问控制和here以获取自定义安全表达式示例,以防您想要自定义解决方案。

答案 3 :(得分:0)

1)首先我们需要知道用户是否可以输入URL。使用WebInvocationPrivilegeEvaluator可以很容易地实现这一点。

privilegeEvaluator.isAllowed(contextPath, url, "GET", currentUser);

2)现在我们需要确定用户是否可以访问处理程序方法

private boolean isAllowedByAnnotation(Authentication currentUser, HandlerMethod method) {
    PreInvocationAuthorizationAdvice advice = new ExpressionBasedPreInvocationAdvice();
    PreInvocationAuthorizationAdviceVoter voter = new PreInvocationAuthorizationAdviceVoter(advice);

    MethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
    PrePostInvocationAttributeFactory factory = new ExpressionBasedAnnotationAttributeFactory(expressionHandler);
    PrePostAnnotationSecurityMetadataSource metadataSource = new PrePostAnnotationSecurityMetadataSource(factory);

    Class<?> controller = method.getBeanType();
    MethodInvocation mi = MethodInvocationUtils.createFromClass(controller, method.getMethod().getName());
    Collection<ConfigAttribute> attributes = metadataSource.getAttributes(method.getMethod(), controller);

    return PreInvocationAuthorizationAdviceVoter.ACCESS_GRANTED == voter.vote(currentUser, mi, attributes);
}

答案 4 :(得分:0)

我们可以创建自定义PermissionEvaluator并使用

hasPermission(身份验证身份验证,Object domainObject,             对象权限)。

  @Override
  protected MethodSecurityExpressionHandler createExpressionHandler() {
    final DefaultMethodSecurityExpressionHandler expressionHandler =
        new DefaultMethodSecurityExpressionHandler();
    expressionHandler.setPermissionEvaluator(new AclPermissionEvaluator(aclService()));
    return expressionHandler;
  }

 @Bean
  public aclServiceImpl aclService() {
    final AclServiceImpl mutableAclService = new AclServiceImpl 
        (authorizationStrategy(), grantingStrategy());
    return mutableAclService;
  }

AclServiceImpl 是MutableAclService

的实现

答案 5 :(得分:0)

最明显有用的注释是 @PreAuthorize ,它决定是否可以实际调用方法。例如(来自“Contacts”示例应用程序)

@PreAuthorize("hasRole('USER')")
public void create(Contact contact);

这意味着只有角色为“ROLE_USER ”的用户才能访问。显然,使用传统配置和所需角色的简单配置属性可以轻松实现相同的目标。但是怎么样:

@PreAuthorize("hasPermission(#contact, 'admin')")
public void deletePermission(Contact contact, Sid recipient, Permission permission);

这里我们实际上使用方法参数作为表达式的一部分来决定当前用户是否具有给定联系人的“admin”权限。内置的 hasPermission()表达式通过应用程序上下文链接到Spring Security ACL模块。

有关详细说明,请参阅此Link