编程语言
首页 > 编程语言> > java – 自定义权限评估程序Spring

java – 自定义权限评估程序Spring

作者:互联网

我想创建一个自定义权限评估程序,以便使用自定义方法@PreAuthorize REST端点.
我将Spring Boot 1.5.3与Web和安全启动器一起使用.

我的进一步用例是检查登录用户是否有权查看指定的id.

在调用REST端点时,我收到以下错误:

org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method hasPermission(null) cannot be found on org.springframework.security.access.expression.method.MethodSecurityExpressionRoot type

我的自定义权限评估程序:

@Component
class CustomPermissionsEvaluator implements PermissionEvaluator {

    public boolean hasPermission(String id) {
        return id.equals("correct");
    }

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}

我的安全配置:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    public MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
        methodSecurityExpressionHandler.setPermissionEvaluator(new CompanyPermissionsEvaluator());
        return methodSecurityExpressionHandler;
    }
}

我的休息控制器:

@RestController
class RestControllerToProtect {

    @PreAuthorize("hasPermission(#id)")
    @GetMapping
    public String methodToProtect(String id) {
        return "Authenticated";
    }
}

堆栈跟踪:

org.springframework.expression.spel.SpelEvaluationException: EL1004E:
Method call: Method hasPermission(null) cannot be found on
org.springframework.security.access.expression.method.MethodSecurityExpressionRoot type

解决方法:

如果没有其他配置,则不能使用不是PermissionEvaluator成员的重载方法(如果要重新配置PermissionEvaluator模式,请参阅this answer).

默认情况下,hasPermission调用应匹配以下签名之一:

hasPermission(Authentication authentication, Object targetDomainObject, Object permission);

hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission);

例:

public class CustomPermissionEvaluator implements PermissionEvaluator {

    private Logger log = LoggerFactory.getLogger(CustomPermissionEvaluator.class);

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal();
        AbstractEntity abstractEntity = (AbstractEntity) targetDomainObject;
        log.debug("User {} trying to access {}-{} with permission {}",
                customUserDetails.getUsername(),
                abstractEntity.getClass().getSimpleName(),
                abstractEntity.getId(),
                permission.toString());
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal();
        log.debug("User {} trying to access {}-{} with permission {}",
                customUserDetails.getUsername(),
                targetType,
                targetId,
                permission.toString());
        return false;
    }
}

控制器:

@RestController
public class RestControllerToProtect {
    // passing targetDomainObject and permission, authentication is detected by SecurityExpressionRoot
    @PreAuthorize("hasPermission(#abstractEntity, 'create')")
    public String methodToProtect(@RequestBody AbstractEntity abstractEntity) {
        return "Authenticated";
    }
}

标签:spring-rest,java,spring-boot,spring-security
来源: https://codeday.me/bug/20190724/1523006.html