Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 自定义安全表达式_Java_Spring Boot_Spring Security - Fatal编程技术网

Java 自定义安全表达式

Java 自定义安全表达式,java,spring-boot,spring-security,Java,Spring Boot,Spring Security,我正在学习如何创建自定义安全表达式的教程,我创建了三个类,但我遇到了错误,我尝试了谷歌的一切,可能是我没有更新或一些。你能解释一下发生了什么事吗 错误: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentExcept

我正在学习如何创建自定义安全表达式的教程,我创建了三个类,但我遇到了错误,我尝试了谷歌的一切,可能是我没有更新或一些。你能解释一下发生了什么事吗

错误:

    Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Failed to evaluate expression 'isComprador()'] with root cause

    Method call: Method isComprador() cannot be found on type org.springframework.security.access.expression.method.MethodSecurityExpressionRoot
MethodSecurityConfig:

@配置
@EnableGlobalMethodSecurity(Prespenabled=true)
公共类方法SecurityConfig扩展了GlobalMethodSecurityConfiguration{
@凌驾
受保护的MethodSecurityExpressionHandler createExpressionHandler(){
返回新的CustomMethodSecurityExpressionHandler();
}
}
CustomMethodSecurityExpressionHandler:

公共类CustomMethodSecurityExpressionHandler扩展了DefaultMethodSecurityExpressionHandler{
私有最终身份验证trustResolver trustResolver=新身份验证TrustResolverImpl();
@凌驾
受保护的MethodSecurityExpressionOperations createSecurityExpressionRoot(身份验证、方法调用){
CustomMethodSecurityExpressionRoot=新的CustomMethodSecurityExpressionRoot(身份验证);
setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
返回根;
}
}
CustomMethodSecurityExpressionRoot:

公共类CustomMethodSecurityExpressionRoot扩展SecurityExpressionRoot实现MethodSecurityExpressionOperations{
私有对象过滤器对象;
私有对象返回对象;
私有对象目标;
公共CustomMethodSecurityExpressionRoot(身份验证){
超级(认证);
}
@凌驾
public void setFilterObject(对象filterObject){
this.filterObject=filterObject;
}
@凌驾
公共对象getFilterObject(){
返回过滤器对象;
}
@凌驾
public void setReturnObject(对象returnObject){
this.returnObject=returnObject;
}
@凌驾
公共对象getReturnObject(){
返回对象;
}
void setThis(对象目标){
this.target=目标;
}
@凌驾
公共对象getThis(){
回报目标;
}
//
公共布尔isComprador(){
final Usuario Usuario=((userdetailsimple)this.getPrincipal()).getUsuario();
返回usuario.getPerfil()==Perfil.compador;
}
公共布尔值isVendedor(){
final Usuario Usuario=((userdetailsimple)this.getPrincipal()).getUsuario();
返回usuario.getPerfil()==Perfil.VENDEDOR;
}
}
谢谢

收件人:,
Carlos Oliveira

我真的建议使用自定义bean,而不是尝试集成到表达式根中。这更易于配置,只需创建一个简单的pojo即可将代码与Spring安全性分离,并使代码更加集中

要使用此方法,请从创建Springbean开始:

@Component
public class Authz {

    public boolean isComprador() {
        // Authentication is the currently logged in user
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication != null && "comprador".equals(authentication.getName());
    }
}
然后可以使用
@beanName.methodName
引用Bean中的方法。在我们的例子中,Bean名称是
authz
,我们的方法是
isComprador
,因此以下方法可以工作:

@Service
public class MessageService {
    // we pass in the name argument into our custom expression Authz.isComprador
    @PreAuthorize("@authz.isComprador()")
    String greetForName(String name) {
        return "Hello " + name;
    }
}
最后,我们只需像正常情况一样启用方法安全性:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration {
}
然后,您可以编写一些单元测试来证明它是有效的:

@SpringBootTest
class DemoApplicationTests {
    @Autowired
    MessageService service;

    @Test
    @WithMockUser // run the test as a user with the default username of user
    void secureWhenForbidden() {
        assertThatCode(() -> service.greetForName("Rob")).isInstanceOf(AccessDeniedException.class);
    }

    @Test
    @WithMockUser("comprador") // run the test as a user with the username of comprador
    void secureWhenGranted() {
        assertThatCode(() -> service.greetForName("Rob")).doesNotThrowAnyException();;
    }
}

您可以在

上找到完整的样品,这是我想要的,非常简单,而且时间很短。我不敢相信,因为大多数人建议在表达式的根处集成它。