【问题标题】:@Autowired not working with custom AccessDecisionVoter@Autowired 不适用于自定义 AccessDecisionVoter
【发布时间】:2017-06-25 13:20:33
【问题描述】:

我正在实现一个自定义 AccessDecisionVoter,并且我有一个 JPA 存储库,我需要在自定义 AccessDecisionVoter 实现中自动装配它。 @Autowire 根本不适用于此类中的服务或 Jpa 存储库。

项目结构

Application.java

@SpringBootApplication
@ComponentScan(basePackages="com")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

DynamicAuthorizationVoter.java

@Component
public class DynamicAuthorizationVoter implements AccessDecisionVoter<FilterInvocation> {
    @Autowired
    private PrivilegeRepository privilegeRepo;

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class clazz) {
        return true;
    }

    @Override
    public int vote(Authentication authentication, FilterInvocation object, Collection<ConfigAttribute> collection) {
        String url = determineModule(object);
        if (authentication == null || authentication instanceof AnonymousAuthenticationToken) {
            return ACCESS_ABSTAIN;
        }

        return isAccessGranted(authentication, object.getRequestUrl())? ACCESS_GRANTED : ACCESS_DENIED;
    }

    String determineModule(FilterInvocation filterObject){
        String url = filterObject.getRequestUrl();
        return url;
    }

    boolean isAccessGranted(Authentication authObject, String url){

        Set<Privilege> privileges = privilegeRepo.findByUrl(url);

        String userRole;
        for(GrantedAuthority authority : authObject.getAuthorities()){
            userRole = authority.getAuthority();
            for(Privilege priv : privileges){
                if(priv.equals(userRole)){
                    return true;
                }
            }
        }

        return false;
    }
}

PrivilegeRepository.java

public interface PrivilegeRepository extends JpaRepository<Privilege, Long> {
    Set<Privilege> findByName(String name);
    Set<Privilege> findByUrl(String url);
}

为了让 @Autowire 在 DynamicAuthorizationVoter 类中工作,我将 @Component 更改为 @Service、@Configuration 以及我在 SO 上找到的所有其他内容,但它们都不起作用。这个 JPA 存储库在其他任何地方都是 @Autowired。

感谢所有帮助。

-阿迪尔

【问题讨论】:

  • Spring Data Jpa 不需要实现这个接口,除非有特定的事情需要做。
  • 您能否提供有关您在应用程序部署期间收到的错误的更多信息?问候,
  • 我在部署过程中没有看到任何错误,除了当 DynamicAuthorizationVoter.voter 方法被命中时,privilegeRepo 为空,这意味着它没有被自动装配。

标签: spring spring-boot spring-security spring-data-jpa


【解决方案1】:

通常,如果您在部署期间没有看到任何错误,autowired 工作正常,因为它是默认需要的。见@Autowired documentation

无论如何,尝试使用@Autowired 构造函数而不是@Autowired 属性。

private PrivilegeRepository privilegeRepo;

@Autowired
public DynamicAuthorizationVoter(PrivilegeRepository privilegeRepo){
  this.privilegeRepo = privilegeRepo;
}

这样,您可以在此构造函数中添加一个断点并对其进行调试,以了解autowire 进程是否正常工作。

另外,请记住,要使用 DynamicAuthorizationVoter 实例,您不得将其声明为 new。您必须在要使用它的相关类中包含以下代码。

@Autowired
AccessDecisionVoter dynamicAuthorizationVoter;

希望对你有帮助,

【讨论】:

    猜你喜欢
    • 2014-10-29
    • 2014-07-16
    • 2013-11-07
    • 1970-01-01
    • 2016-04-29
    • 2019-05-18
    • 2013-11-05
    • 2015-05-16
    • 2020-12-05
    相关资源
    最近更新 更多