Java 如何将基于方法的安全性添加到Spring启动项目中?

Java 如何将基于方法的安全性添加到Spring启动项目中?,java,spring,spring-security,spring-boot,Java,Spring,Spring Security,Spring Boot,我想将基于方法的安全性添加到Spring启动项目中 我似乎只需要添加PermissionEvaluator和MethodSecurityExpressionHandlerbean,用@EnableGlobalMethodSecurity(prePostEnabled=true)和@PreAuthorize(“isAuthenticated()和hasspermission”)注释我的WebSecurityConfigureAdapter(#param,'somePermissionName'))

我想将基于方法的安全性添加到Spring启动项目中

我似乎只需要添加
PermissionEvaluator
MethodSecurityExpressionHandler
bean,用
@EnableGlobalMethodSecurity(prePostEnabled=true)
@PreAuthorize(“isAuthenticated()和hasspermission”)注释我的
WebSecurityConfigureAdapter
(#param,'somePermissionName'))

但是在添加
PermissionEvaluator
bean之后

@Bean
公共许可评估器许可评估器(){
HelloperMissioneEvaluator bean=新的HelloperMissioneEvaluator();
返回豆;
}
我得到一个
IllegalArgumentException
:“需要一个servlet上下文来配置默认的servlet处理”:

HelloController.java

package com.domain.simple;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.security.access.prepost.PreAuthorize;
导入org.springframework.stereotype.Controller;
导入org.springframework.web.bind.annotation.PathVariable;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.ResponseBody;
@控制器
公共类Hello控制器{
Logger log=LoggerFactory.getLogger(HelloController.class);
//@PreAuthorize(“isAuthenticated()和hasPermission(#param,'somePermissionName'))
@RequestMapping(value=“/hello/{param}”)
@应答器
公共字符串hello(@PathVariable(“param”)字符串param){
log.info(“hello(“+param+”)调用”);
返回“Hello”+param;
}
}
HelloPermissionEvaluator.java

package com.domain.simple;
导入java.io.Serializable;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.security.access.PermissionEvaluator;
导入org.springframework.security.core.Authentication;
公共类HelloperCommissionEvaluator实现PermissionEvaluator{
Logger log=LoggerFactory.getLogger(HelloPermissionEvaluator.class);
@凌驾
公共权限(身份验证,
对象targetDomainObject,对象权限){
log.info(“hasPermission(身份验证、对象、对象)调用”);
返回true;
}
@凌驾
公共权限(身份验证,
可序列化的targetId、字符串targetType、对象权限){
错误(“hasPermission(身份验证、可序列化、字符串、对象)调用”);
抛出新的RuntimeException(“当前不支持基于ID的权限评估”);
}
}
WebSecurityConfig.java

package com.domain.simple;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.ComponentScan;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.security.access.PermissionEvaluator;
导入org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
导入org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
导入org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
导入org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
导入org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
导入org.springframework.security.config.annotation.web.configuration.websecurityConfigureAdapter;
@配置
@组件扫描
@启用Web安全性
@EnableGlobalMethodSecurity(Prespenabled=true)
公共类WebSecurityConfig扩展了WebSecurityConfigureAdapter{
@凌驾
受保护的无效配置(AuthenticationManagerBuilder authManagerBuilder)
抛出异常{
authManagerBuilder.inMemoryAuthentication().withUser(“用户”)
.密码(“密码”)。角色(“用户”);
}
//@Bean
//public MethodSecurityExpressionHandler expressionHandler(){
//DefaultMethodSecurityExpressionHandler bean=新的DefaultMethodSecurityExpressionHandler();
//setPermissionEvaluator(permissionEvaluator());
//返回豆;
//    }
//这会导致IllegalArgumentException(“配置默认servlet处理需要ServletContext”)
@豆子
公共许可评估器许可评估器(){
HelloperMissioneEvaluator bean=新的HelloperMissioneEvaluator();
返回豆;
}
}
格雷德尔先生

buildscript{
存储库{
maven{url“http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
依赖关系{
类路径(“org.springframework.boot:springbootgradle插件:1.0.2.RELEASE”)
}
}
应用插件:“eclipse”
应用插件:“java”
应用插件:“spring boot”
罐子{
baseName='simple'
版本='0.1.0'
}
存储库{
mavenCentral()
maven{url“http://repo.spring.io/libs-snapshot" }
}
依赖关系{
编译(“org.springframework.boot:springbootstarterweb”)
编译(“org.springframework.boot:springbootstartersecurity”)
}
任务包装器(类型:包装器){
gradleVersion='1.12'
}

尝试将
PermissionEvaluator
放在一个单独的
@Configuration
类中。您似乎在
ServletContext
准备就绪之前强制将其实例化(必须提前创建Spring安全筛选器,这样才能实现此目的).

遇到类似问题。如果要在表达式处理程序中配置自定义权限计算器,可以执行以下操作

public class SecurityPermissionEvaluator implements PermissionEvaluator 
    {
    //A is a spring managed bean on which permission evaluator depends
    private A a;

    @Autowired
    public  SecurityPermissionEvaluator(A a){
        this.a = a;
    }
    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {

        return false;
    }
}

then

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

    @Autowired private A a;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler =
                new DefaultMethodSecurityExpressionHandler();
        PermissionEvaluator permissionEvaluator = new SecurityPermissionEvaluator(a);
        expressionHandler.setPermissionEvaluator(permissionEvaluator);
        return expressionHandler;
    }

}

如果您想显式使用权限计算器,请按照Dave ie在其on config文件中定义权限计算器bean的建议执行上述操作。

您能提供一个最终解决方案的概览吗?我的情况与此类似。
public class SecurityPermissionEvaluator implements PermissionEvaluator 
    {
    //A is a spring managed bean on which permission evaluator depends
    private A a;

    @Autowired
    public  SecurityPermissionEvaluator(A a){
        this.a = a;
    }
    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {

        return false;
    }
}

then

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

    @Autowired private A a;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler =
                new DefaultMethodSecurityExpressionHandler();
        PermissionEvaluator permissionEvaluator = new SecurityPermissionEvaluator(a);
        expressionHandler.setPermissionEvaluator(permissionEvaluator);
        return expressionHandler;
    }

}