복붙노트

[SPRING] 봄 + 봄 보안 + hasPermission 작동하지 않습니다

SPRING

봄 + 봄 보안 + hasPermission 작동하지 않습니다

Struts 2와 Spring DI에서 Spring Security 3을 사용하려고합니다. 내 코드에 hasRole () 주석을 넣었지만 정상적으로 작동하지만 hasPermission () 주석이 작동하지 않습니다. 표현 처리기, 사용자 정의 권한 평가 기 등을 만들었습니다.

여기에 코드가있다.

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입니다.

<?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입니다.

 <?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입니다.     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입니다.

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입니다.

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 ()이 작동하지 않는지 말해 주시겠습니까?

해결법

  1. ==============================

    1.Spring AOP는 Bean 간의 호출을 가로 채기 만 할 수 있기 때문에 작동하지 않지만 같은 Bean의 메소드를 호출하는 경우에는 작동하지 않습니다.

    Spring AOP는 Bean 간의 호출을 가로 채기 만 할 수 있기 때문에 작동하지 않지만 같은 Bean의 메소드를 호출하는 경우에는 작동하지 않습니다.

    그래서 isAccessible 메소드를 다른 bean으로 옮기거나 Spring Proxy AOP 대신 AspectJ를 사용한다.

    또 다른 아이디어는 어노테이션 된 메소드를 갖는 대신 권한 평가를 직접 사용하는 것입니다. (그러나 나는 이것이 어떻게 행해질 수 있는지 정확하게 모른다.)

  2. from https://stackoverflow.com/questions/8208501/spring-spring-security-haspermission-not-working by cc-by-sa and MIT license