Spring + Spring Security + hasPermission无法正常工作 [英] Spring + Spring Security + hasPermission Not working

查看:124
本文介绍了Spring + Spring Security + hasPermission无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Spring Security 3与Struts 2和Spring DI一起使用.我在代码中放入了hasRole()注释,它可以正常工作,但是hasPermission()注释不起作用.我已经制作了表达式处理程序,自定义权限评估器等.

I am trying to use Spring Security 3 with Struts 2 and Spring DI. I put hasRole() annotation in my code and it is working fine but hasPermission() annotation is not working. I have made expression handler, custom permission evaluator etc.

这是代码

applicationContext.xml

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans> 
 <import resource="mySecurity.xml"/>
<bean id="myAction" name="myAction" class="code.action.MyAction" autowire="byName">
</bean>
<bean id="permission" name="permission" class="code.permission.Permission" autowire="byName">
</bean>
<bean id="myEntity" name="myEntity" class="code.entities.MyEntity" autowire="byName">
</bean>
<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler" 
    name="expressionHandler" autowire="byName">
</bean>
<bean class="code.permission.MyCustomPermissionEvaluator" id="customPermissionEvaluator" name="customPermissionEvaluator" autowire="byName" />
</beans>

这是我的acl-context.xml

Here is my acl-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/util
   http://www.springframework.org/schema/util/spring-util-3.0.xsd">

    <!-- Declare a simple map containing all our roles -->
    <util:map id="permissionsMap">
         <entry key="ROLE_USER" value-ref="user"/>
     </util:map>

 <!-- Declare permissions for Admin
  Contains a map of objects and their associated allowed actions -->
 <bean id="user" class="code.permission.Permission" >
  <property name="objects">
   <map>
    <entry key="code.entities.MyEntity">
     <list>
      <value>READ</value>
     </list>
    </entry>
   </map>
  </property>
 </bean>

</beans>

这是mySecurity.xml

this is mySecurity.xml

 <?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.1.xsd">

  <!-- To enable Method Security Expressions and custom PermissionEvaluator
   we need to add the following -->
         <global-method-security pre-post-annotations="enabled">
                <expression-handler ref="expressionHandler" />
         </global-method-security>

 <!-- To use hasPermission() expressions, we have to configure a PermissionEvaluator -->
 <!-- See 15.3.2 Built-In Expression
   @http://static.springsource.org/spring-security/site/docs/3.0.x/reference/el-access.html#el-permission-evaluator -->
        <beans:bean id="expressionHandler"
            class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler" name="expressionHandler" autowire="byName">
        <beans:property name="permissionEvaluator" ref="customPermissionEvaluator" />
        <beans:property name = "roleHierarchy" ref="roleHierarchy"/>
     </beans:bean>

 <!-- Declare a custom PermissionEvaluator interface -->
 <beans:bean class="code.permission.MyCustomPermissionEvaluator" id="customPermissionEvaluator" name="customPermissionEvaluator" autowire="byName" />

    <http auto-config="true" use-expressions="true">
    <intercept-url pattern="/index.jsp" access="permitAll" />
    <intercept-url pattern="/firstPage" access="hasRole('ROLE_USER')" />
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="user" password="user" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>

    <!-- http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.html -->
    <beans:bean id="roleHierarchy"  class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl" name="roleHierarchy" autowire="byName">
      <beans:property name="hierarchy">
         <beans:value>
             ROLE_USER
         </beans:value>
     </beans:property>
    </beans:bean>
 </beans:beans>

这是我的Permission.java 包裹代码.权限;

This is my Permission.java package code.permission;

import java.util.List;
import java.util.Map;

/**
 * Contains a map of objects and their associated allowed actions
 */
public class Permission {

 /**
  *  A Map containing a list of objects and their corresponding actions
  *  <p>
  *  String: key name of the object
  *  List<String>: a list of permissions
  */
  private Map<String, List<String>> objects;

 public Map<String, List<String>> getObjects() {
  return objects;
 }
 public void setObjects(Map<String, List<String>> objects) {
  this.objects = objects;
 }

}

这是myCustomPermissionEvaluator.java

This is myCustomPermissionEvaluator.java

package code.permission;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;

import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import javax.annotation.Resource;

public class MyCustomPermissionEvaluator implements PermissionEvaluator {

  @Resource(name="permissionsMap")
   private Map permissionsMap;

 @Resource(name="roleHierarchy")
 private RoleHierarchy roleHierarchy;

 public boolean hasPermission(Authentication authentication,
   Object targetDomainObject, Object permission) {
     System.out.println("First hasPermission");

  String role = getRole(authentication);

  return hasPermission(role, permission, targetDomainObject);
 }

 /**
  * Another hasPermission signature. We will not implement this.
  */
 public boolean hasPermission(Authentication authentication,
    Serializable targetId, String targetType, Object permission) {

  return false;
 }

 /**
  * Retrieves the user's highest role
  */
 private String getRole(Authentication authentication) {
  String highestRole = null;

  try {
    Collection<GrantedAuthority> auths = (Collection<GrantedAuthority>)   roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
   for (GrantedAuthority auth: auths) {
    highestRole = auth.getAuthority();
    break;
   }

  } catch (Exception e) {

  }

  return highestRole;
 }

 private Boolean hasPermission(String role, Object permission, Object domain) {
     System.out.println("Second hasPermission");
  if ( permissionsMap.containsKey(role) ) {
        Permission userPermission = (Permission) permissionsMap.get(role);

  if ( userPermission.getObjects().containsKey(domain.getClass().getName())){

    for (String action: userPermission.getObjects().get(domain.getClass().getName()) ) {
      if (action.equals(permission)) {

       return true;
     }
    }
   }
  }

  return false;
 }
}

这是MyAction.java

this is MyAction.java

package code.action;

import org.springframework.security.access.prepost.PreAuthorize;
import code.entities.MyEntity;

public class MyAction {
    @PreAuthorize("hasRole('ROLE_USER')")
    public String showPage(){
        System.out.println("in MyAction : showPage");
        MyEntity entity = new MyEntity();
        if(isAccessible(entity))
            return "success";
        else
            return "input";
    }
     @PreAuthorize("hasPermission(#entity,'WRITE')")
    public boolean isAccessible(MyEntity entity){
        System.out.println("in MyAction : isAccessible");
        return true;
    }
}

这里有专家告诉我为什么hasPermission()不起作用吗?

Any expert here to tell me why this hasPermission() not working ?

推荐答案

它不起作用,因为Spring AOP只能识别bean之间的调用,而不能调用同一bean的方法.

It does not work, because Spring AOP can only incercept calls between beans, but not if you invoke a method of the same bean.

因此,您可以将isAccessible方法移至另一个bean,或者使用use AspectJ代替Spring Proxy AOP.

So either you move the isAccessible Method to an other bean, or use use AspectJ instead of Spring Proxy AOP.

另一个想法是直接使用权限评估,而不是使用带注释的方法. (但是我不知道该怎么做.)

An other idea would be using the permission evaluation directly, instead of having the annotated method. (But I do not know exactly how this can be done.)

这篇关于Spring + Spring Security + hasPermission无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆