Spring 安全 @PreAuthorize NullPointerException。为啥?
Posted
技术标签:
【中文标题】Spring 安全 @PreAuthorize NullPointerException。为啥?【英文标题】:Spring security @PreAuthorize NullPointerException. Why?Spring 安全 @PreAuthorize NullPointerException。为什么? 【发布时间】:2020-07-06 06:40:45 【问题描述】:我正在尝试在控制器中检查用户的角色,因此当用户调用特定的网址时,他可以访问该页面(或不访问)。
所以我将 @PreAuthorize("hasPermission...) 放在我的控制器方法之一中并创建了我的自定义 * PermissionEvaluator*。它需要两个字符串作为参数(实体名称 - 字符串,权限名称 - 字符串),稍后我将从用户的角色对象中获取。出于测试目的,它始终返回 true。
问题:我在放置@PreAuthorize 时总是得到NullPointerException。你能解释一下我做错了什么吗?
控制器
@RequestMapping(value = "goal/new", method = RequestMethod.GET)
@PreAuthorize("hasPermission('GOAL', 'WRITE')")
public String add (Model model, RedirectAttributes redirect)
User user = AuthUtils.getCurrentUser();
Goal goal = new Goal();
Set<Unit> units = unitService.getUnitsByRole(user.getRoles());
model.addAttribute("goal", goal);
model.addAttribute("units", units);
return WEB_FORM_URL;
权限评估器
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission)
System.out.println("Permission eveluator: called");
boolean permissionGranted = true;
return permissionGranted;
@Override
public boolean hasPermission(Authentication authentication, Serializable serializable, String targetType,
Object permission)
return false;
GlobalMethodSecurityConfiguration
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true, proxyTargetClass = true)
public class CustomMethodSecurityConfig extends GlobalMethodSecurityConfiguration
@Autowired
CustomPermissionEvaluator permissionEvaluator;
@Bean
public MethodSecurityExpressionHandler methodSecurityExpressionHandler()
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
handler.setPermissionEvaluator(permissionEvaluator);
return handler;
错误堆栈
java.lang.NullPointerException: null
at org.springframework.security.access.expression.SecurityExpressionRoot.hasPermission(SecurityExpressionRoot.java:177) ~[spring-security-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:130) ~[spring-expression-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:138) ~[spring-expression-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:94) ~[spring-expression-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114) ~[spring-expression-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:300) ~[spring-expression-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:26) ~[spring-security-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:59) ~[spring-security-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
【问题讨论】:
【参考方案1】:我不是 100% 确定,但您能否更改 CustomMethodSecurityConfig 中的方法签名以实际覆盖 GlobalMethodSecurityConfiguration 中的正确方法。
所以
@Override
protected MethodSecurityExpressionHandler createExpressionHandler()
而不是
@Bean
public MethodSecurityExpressionHandler methodSecurityExpressionHandler()
【讨论】:
将“@Override”添加到公共 MethodSecurityExpressionHandler 而不是“@Bean”。现在我得到一个错误“方法没有覆盖或实现超类型的方法”。 是的,因为您还需要更改方法名称以匹配。确保将其命名为“createExpressionHandler” 有效。谢谢!以上是关于Spring 安全 @PreAuthorize NullPointerException。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
spring boot(1.3)基于oauth2资源服务器:不能使用@PreAuthorize方法安全
如何在@PreAuthorize注释中传递调用自定义方法的spring句柄
Spring Security SAML 扩展和@PreAuthorize
使用 @PreAuthorize 的 GraphQL 和 Spring Security?
Spring @PreAuthorize 抛出 LazyInitializationException 从 Hibernate 访问惰性数据