Spring security 使用查询方法发布SpringSecurity4

Spring security 使用查询方法发布SpringSecurity4,spring-security,spring-data-jpa,Spring Security,Spring Data Jpa,我使用的是最新的SpringSecurity4版本,它引入了一个新功能,使用表达式语言直接在查询方法中使用登录的用户详细信息。以下是我的spring数据存储库代码: public interface UserRepository extends JpaRepository<User, Long> { @Query("select username from User u where u.username = ?#{ principal?.username }") Us

我使用的是最新的SpringSecurity4版本,它引入了一个新功能,使用表达式语言直接在查询方法中使用登录的用户详细信息。以下是我的spring数据存储库代码:

public interface UserRepository extends JpaRepository<User, Long> {
    @Query("select username from User u where u.username = ?#{ principal?.username }")
    User findByUsername(String username);
}
此外,我还有以下条目用于启用此功能:

@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
    return new SecurityEvaluationContextExtension();
}
当我运行应用程序时,会出现以下错误:

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Authentication object cannot be null; nested exception is java.lang.IllegalArgumentException: Authentication object cannot be null
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417) 
Caused by: java.lang.IllegalArgumentException: Authentication object cannot be null
    at org.springframework.security.access.expression.SecurityExpressionRoot.<init>(SecurityExpressionRoot.java:46)
    at org.springframework.security.data.repository.query.SecurityEvaluationContextExtension$1.<init>(SecurityEvaluationContextExtension.java:113)
    at org.springframework.security.data.repository.query.SecurityEvaluationContextExtension.getRootObject(SecurityEvaluationContextExtension.java:113)
    at org.springframework.data.repository.query.ExtensionAwareEvaluationContextProvider$EvaluationContextExtensionAdapter.<init>(ExtensionAwareEvaluationContextProvider.java:463)
    at org.springframework.data.repository.query.ExtensionAwareEvaluationContextProvider.toAdapters(ExtensionAwareEvaluationContextProvider.java:210)
    at org.springframework.data.repository.query.ExtensionAwareEvaluationContextProvider.access$000(ExtensionAwareEvaluationContextProvider.java:58)

请尝试此自定义类:-

class SecurityEvaluationContextExtension extends  EvaluationContextExtensionSupport  {

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

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

不确定您是否同时解决了该问题,但我注意到您的查询应该如下所示:

从用户u中选择u,其中u.username=?{principal}


假设您的主要对象是普通用户名字符串

如果您创建了自己的SecurityEvaluationContextExtension类,并且没有实现getAuthentication方法,则可能会出现此异常

在这里,您可以看到原始的SecurityEvaluationContextension.java文件,该文件实现了所有必要的方法

因此,您不需要自己实现这个类。相反,您可以将下面的依赖项添加到pom文件中,以获得原始文件

<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-data -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-data</artifactId>
    <version>4.2.1.RELEASE</version>
</dependency>
如果您使用的是任何其他依赖项管理器而不是maven,那么可以转到并获得所需的定义


我希望这有帮助。

我添加了这个自定义类。那么它也不起作用了。
class SecurityEvaluationContextExtension extends  EvaluationContextExtensionSupport  {

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

  @Override 
  public SecurityExpressionRoot getRootObject() { 
    Authentication authentication =  SecurityContextHolder.getContext().getAuthentication(); 
    return new SecurityExpressionRoot(authentication){}; 
  } 
}
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-data -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-data</artifactId>
    <version>4.2.1.RELEASE</version>
</dependency>