这里是GitHub of my mini-project(如果需要)。
我无法理解SpEL表达式。当我尝试从这个tutorial实现代码时,我得到了以下错误:
1.
@PreAuthorize("hasRole('ROLE_USER')")
public interface TodoRepo extends PagingAndSortingRepository<TodoEntity, Long> {
@Override
@PreAuthorize("#todo?.entity == null or #todo?.entity?.name == authentication?.name")
TodoEntity save(@Param("todo") TodoEntity employee);
@Override
@PreAuthorize("@todoRepo.findById(#id)?.entity?.name == authentication?.name")
void deleteById(@Param("id") Long id);
@Override
@PreAuthorize("#todo?.entity?.name == authentication?.name")
void delete(@Param("todo") TodoEntity employee);
}
错误:
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'name' cannot be found on object of type 'com.egor.todo.entity.UserEntity' - maybe not public or not valid?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:217) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:104) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:51) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:406) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:92) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.OpEQ.getValueInternal(OpEQ.java:42) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.OpEQ.getValueInternal(OpEQ.java:32) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:188) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.OpOr.getBooleanValue(OpOr.java:56) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.OpOr.getValueInternal(OpOr.java:51) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.OpOr.getValueInternal(OpOr.java:37) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:309) ~[spring-expression-5.3.23.jar:5.3.23]
at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30) ~[spring-security-core-5.7.4.jar:5.7.4]
... 17 common frames omitted
@PreAuthorize("hasRole('ROLE_USER')")
public interface TodoRepo extends PagingAndSortingRepository<TodoEntity, Long> {
@Override
@PreAuthorize("#todo?.getEntity() == null or #todo?.getEntity()?.getName() == authentication?.name")
TodoEntity save(@Param("todo") TodoEntity employee);
@Override
@PreAuthorize("@todoRepo.findById(#id)?.getEntity()?.getName() == authentication?.name")
void deleteById(@Param("id") Long id);
@Override
@PreAuthorize("#todo?.getEntity()?.getName() == authentication?.name")
void delete(@Param("todo") TodoEntity employee);
}
错误:
Caused by: org.springframework.security.access.AccessDeniedException: Доступ запрещен
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:73) ~[spring-security-core-5.7.4.jar:5.7.4]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.attemptAuthorization(AbstractSecurityInterceptor.java:239) ~[spring-security-core-5.7.4.jar:5.7.4]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:208) ~[spring-security-core-5.7.4.jar:5.7.4]
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:58) ~[spring-security-core-5.7.4.jar:5.7.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy107.save(Unknown Source) ~[na:na]
at com.egor.todo.DatabaseLoader.run(DatabaseLoader.java:40) ~[classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771) ~[spring-boot-2.7.5.jar:2.7.5]
... 5 common frames omitted
实体:
TodoEntity.java
package com.egor.todo.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import java.util.Objects;
@Entity
public class TodoEntity {
private @Id @GeneratedValue long id;
private String name;
private String description;
private boolean done;
private @ManyToOne UserEntity entity;
public UserEntity getEntity() {
return entity;
}
public void setEntity(UserEntity entity) {
this.entity = entity;
}
public TodoEntity() {
}
public TodoEntity(String name, String description, boolean done, UserEntity entity) {
this.name = name;
this.description = description;
this.done = done;
this.entity = entity;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TodoEntity that = (TodoEntity) o;
return id == that.id && done == that.done && Objects.equals(name, that.name) && Objects.equals(description, that.description);
}
@Override
public int hashCode() {
return Objects.hash(id, name, description, done);
}
@Override
public String toString() {
return "TodoEntity{" +
"id=" + id +
", name='" + name + '\'' +
", description='" + description + '\'' +
", done=" + done +
'}';
}
}
UserEntity.java
package com.egor.todo.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.util.Arrays;
import java.util.Objects;
@Entity
public class UserEntity {
public static final PasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();
private @Id @GeneratedValue Long id;
private String name;
private @JsonIgnore String password;
private String[] roles;
public void setPassword(String password) {
this.password = PASSWORD_ENCODER.encode(password);
}
public UserEntity() {}
public UserEntity(String name, String password, String... roles) {
this.name = name;
this.setPassword(password);
this.roles = roles;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity entity = (UserEntity) o;
return Objects.equals(id, entity.id) &&
Objects.equals(name, entity.name) &&
Objects.equals(password, entity.password) &&
Arrays.equals(roles, entity.roles);
}
@Override
public int hashCode() {
int result = Objects.hash(id, name, password);
result = 31 * result + Arrays.hashCode(roles);
return result;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public String[] getRoles() {
return roles;
}
public void setRoles(String[] roles) {
this.roles = roles;
}
@Override
public String toString() {
return "UserEntity{" +
"id=" + id +
", name='" + name + '\'' +
", roles=" + Arrays.toString(roles) +
'}';
}
}
我在努力:
将调用字段更改为getter,然后返回。
问题还没解决什么
更改日志:
1.我又加了一个实体代码。
1条答案
按热度按时间daupos2t1#
事实证明,我在调用“
public UsernamePasswordAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities)
“构造函数时输入了错误的参数。必须在“principal
“字段中输入与UserEntity构造函数的“name
“字段中相同的值。