首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在查询时使用Security表达式时的SpelEvaluationException

在查询时使用Security表达式时的SpelEvaluationException
EN

Stack Overflow用户
提问于 2018-01-27 18:16:03
回答 1查看 955关注 0票数 0

我试图在查询中使用Security表达式。如36.@Query中的安全表达式所示

代码语言:javascript
复制
public interface BookRepository extends JpaRepository<Book, Long> {
    @PreAuthorize("hasAuthority('AUTHOR')")
    @Query("select b from Book b where b.author.id = ?#{ principal?.id }")
    Page<Book> findAllOwned(Pageable p);
}

我得到了下面的错误。

代码语言:javascript
复制
2018-01-28 01:50:10.672 ERROR 12985 --- [nio-8443-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'aid' cannot be found on object of type 'java.lang.String' - maybe not public?] with root cause

org.springframework.expression.spel.SpelEvaluationException: 
EL1008E: 
Property or field 'id' cannot be found on object of type 'java.lang.String' - maybe not public?

请帮助解决这个问题。我做错了什么?我在下面列出了我认为有必要和与这个问题相关的课程。

我已经定义了

代码语言:javascript
复制
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
    return new SecurityEvaluationContextExtension();
}

和用户详细服务。

代码语言:javascript
复制
@Component
public class AppUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(s);

        if (user == null) {
            throw new UsernameNotFoundException(String.format("The username %s doesn't exist", s));
        }

        List<GrantedAuthority> authorities = new ArrayList<>();
        user.getRoles()
                .forEach(role -> {
                    authorities.add(new SimpleGrantedAuthority(role.getRoleName()));
                });

        return new PrincipalUser(user.getId(), user.getUsername(), user.getPassword(), authorities);

    }
}

自定义主用户

代码语言:javascript
复制
public class PrincipalUser extends User {
    private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
    private Long id;

    public PrincipalUser(Long id, String username, String password, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, authorities);
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

图书实体

代码语言:javascript
复制
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "book")
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "name", unique=true)
    private String name;

    @Column(name = "shortcode")
    private String shortcode;

    @ManyToOne
    @JoinColumn(name="author_user_id")
    private User author;

    @CreatedDate
    @Column(name = "created_date", columnDefinition="DATETIME")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;

    @CreatedBy
    @Column(name="created_by")
    private String createdBy;

    @LastModifiedDate
    @Column(name = "last_modified_date", columnDefinition="DATETIME")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;

    @LastModifiedBy
    @Column(name="last_modified_by")
    private String lastModifiedBy;

    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 getShortcode() {
        return shortcode;
    }

    public void setShortcode(String shortcode) {
        this.shortcode = shortcode;
    }

    public User getAuthor() {
        return author;
    }

    public void setAuthor(User author) {
        this.author = author;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public Date getLastModifiedDate() {
        return lastModifiedDate;
    }

    public void setLastModifiedDate(Date lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }

    public String getLastModifiedBy() {
        return lastModifiedBy;
    }

    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }
}

用户实体

代码语言:javascript
复制
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "app_user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "username", unique=true)
    private String username;

    @Column(name = "password")
    @JsonDeserialize(using = BCryptPasswordDeserializer.class )
    private String password;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    @Column(name = "is_active")
    private boolean isActive;

    @CreatedDate
    @Column(name = "created_date", columnDefinition="DATETIME")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;

    @CreatedBy
    @Column(name="created_by")
    private String createdBy;

    @LastModifiedDate
    @Column(name = "last_modified_date", columnDefinition="DATETIME")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;

    @LastModifiedBy
    @Column(name="last_modified_by")
    private String lastModifiedBy;

    @OneToMany(mappedBy="author")   
    private List<Book> authoredBooks;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "user_role", joinColumns
            = @JoinColumn(name = "user_id",
            referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "role_id",
                    referencedColumnName = "id"))
    private List<Role> roles;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public boolean isActive() {
        return isActive;
    }

    public void setActive(boolean isActive) {
        this.isActive = isActive;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public Date getLastModifiedDate() {
        return lastModifiedDate;
    }

    public void setLastModifiedDate(Date lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }

    public String getLastModifiedBy() {
        return lastModifiedBy;
    }

    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    public List<Book> getAuthoredBooks() {
        return authoredBooks;
    }

    public void setAuthoredBooks(List<Book> authoredBooks) {
        this.authoredBooks = authoredBooks;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
}

扩展SecurityEvaluationContextExtension

代码语言:javascript
复制
class SecurityEvaluationContextExtension extends EvaluationContextExtensionSupport {

  @Override
  public String getExtensionId() {
    return "security";
  }

  @Override
  public SecurityExpressionRoot getRootObject() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    return new SecurityExpressionRoot(authentication) {};
  }
}

堆栈跟踪的前几行:

代码语言:javascript
复制
ERROR 18238 --- [nio-8443-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'id' cannot be found on object of type 'java.lang.String' - maybe not public?] with root cause

org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'id' cannot be found on object of type 'java.lang.String' - maybe not public?
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:226) ~[spring-expression-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94) ~[spring-expression-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:46) ~[spring-expression-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:379) ~[spring-expression-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) ~[spring-expression-4.3.13.RELEASE.jar:4.3.13.RELEASE]

全套追踪..。

EN

回答 1

Stack Overflow用户

发布于 2018-01-30 12:43:11

似乎有什么不相干的吗?在这个例子中。尝试:

代码语言:javascript
复制
@Query("select b from Book b where b.author.id = ?#{principal.id}")
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48478982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档