gpt4 book ai didi

java - 自定义安全表达式

转载 作者:行者123 更新时间:2023-12-05 02:48:31 26 4
gpt4 key购买 nike

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

错误:

    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

方法安全配置:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new CustomMethodSecurityExpressionHandler();
}
}

CustomMethodSecurityExpressionHandler:

public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();

@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
return root;
}
}

自定义方法安全表达式根:

public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {

private Object filterObject;
private Object returnObject;
private Object target;

public CustomMethodSecurityExpressionRoot(Authentication authentication) {
super(authentication);
}

@Override
public void setFilterObject(Object filterObject) {
this.filterObject = filterObject;
}

@Override
public Object getFilterObject() {
return filterObject;
}

@Override
public void setReturnObject(Object returnObject) {
this.returnObject = returnObject;
}

@Override
public Object getReturnObject() {
return returnObject;
}

void setThis(Object target) {
this.target = target;
}

@Override
public Object getThis() {
return target;
}

//

public boolean isComprador() {
final Usuario usuario = ((UserDetailsImpl) this.getPrincipal()).getUsuario();
return usuario.getPerfil() == Perfil.COMPRADOR;
}

public boolean isVendedor() {
final Usuario usuario = ((UserDetailsImpl) this.getPrincipal()).getUsuario();
return usuario.getPerfil() == Perfil.VENDEDOR;
}
}

谢谢!

注意,卡洛斯·奥利维拉

最佳答案

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

要使用这种方法,首先要创建一个 Spring Bean:

@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();;
}
}

您可以在 https://github.com/rwinch/spring-security-sample/tree/method-security-bean-expression 找到完整的示例

关于java - 自定义安全表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64438498/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com