使用 Spring Security 的自动装配依赖注入

Posted

技术标签:

【中文标题】使用 Spring Security 的自动装配依赖注入【英文标题】:Autowired Dependency Injection with Spring Security 【发布时间】:2013-05-03 13:11:23 【问题描述】:

我有一个带有注释驱动配置的 spring webapp。

所有控制器、存储库都是自动装配的。

在集成 Spring Security 时,我定义了一个单独的 security-app.xml。我创建了一个名为 LoginUserService 的服务,它实现了 UserDetailsS​​ervice。现在调用这个类的 loadUserByUsername() 方法进行身份验证。

这个类对 UserRepository 有一个自动装配的依赖。现在这个自动装配的依赖项变成了空值。为了解决这个问题,我启用注释驱动配置并在组件扫描配置中添加存储库类的包名称。

这里也讨论了这个解决方案 spring security with custom user details

但现在的问题是 UserRepository 有一个带有 @PersistenceContext 注释的 EntityManager 字段。对于 spring 安全配置,它能够定位 UserRepository 但无法定位实体管理器。我应该在这里创建一个新的 EntityManagerFactory 吗?我猜这会在我的应用程序中创建两个持久性单元?

如何向使用原始 servlet xml 创建的 UserRepository 注入自动装配的依赖项?

更新

这里简要讨论一下: https://***.com/a/7078395/161628

但我想规范的详细答案对我来说会更有用。

更新

在运行时使用 ApplicationContext 获取 UserRepository 怎么样?

if (userRepository == null) 
    userRepository = ApplicationContextProvider.getApplicatonContext().getBean(UserRepository.class);

Why is Spring's ApplicationContext.getBean considered bad?

【问题讨论】:

【参考方案1】:

编辑: 您在配置中为 DispatcherServlet 声明的 Bean 将不可用于您在 contextConfigLocation 配置文件中声明或组件扫描的任何 bean。因此,在这种情况下,如果您在为 DispatcherServlet 加载的配置文件中设置 JPA 配置,则无法将其连接到您在安全配置中声明的 bean。您需要将任何类似的“核心”bean 配置(数据源配置、数据库连接池配置、JPA/Hibernate 配置、存储库/服务组件扫描等)移动到您通过 contextConfigLocation 加载的配置文件中。然后,您的安全 bean 和 MVC bean 都可以使用这些东西。我认为通常的想法是只在 DispatcherServlet 配置中加载 MVC 特定的 bean(例如控制器、视图、请求处理程序、请求范围的 bean 等)。这样你就可以确保你在 MVC 代码和非 MVC 代码之间有一个清晰的分离,只有从 MVC 代码到“核心”代码的单向依赖,并且在你的“核心”代码中没有对 MVC 代码的依赖。这有助于使您的代码更加模块化,并更容易以其他方式重用您的“核心”代码,特别是在单元测试中。

(原始评论文本询问如何加载安全配置,如果它在 contextConfigLocation 或其他地方。)

【讨论】:

我这里没有 app-config.xml。只是 context-param 中的 security-config.xml。 app-config.xml 是使用 DispatcherServlet 加载的。 Spring Security 配置使用 contextConfigLocation 加载。 通过在两个 xml 文件中复制配置会为 EntityManagerFactory 获得 NoSuchBeanDefinitionException,因为有两个 bean 而不是一个。 我已根据您的回复和其他信息更新了我的答案。我认为你基本上需要重新安排你的配置。您应该只在 DispatcherServlet 配置中包含 MVC 内容,并将非 MVC 内容(例如 JPA 配置)移动到您通过 contextConfigLocation 加载的另一个文件。 感谢您的帮助。现在我通过在运行时从 ApplicationContext 加载存储库 bean 来让它工作。我将按照您的描述重构配置。

以上是关于使用 Spring Security 的自动装配依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security:自动装配 ProviderManager

Spring Security:自动装配 ProviderManager

Spring Security @PreAuthorize 使用 SpEL 语言访问自动装配的 bean [重复]

Spring security 无法自动装配 UserDetailsS​​ervice

Spring Security WebSecurityConfigurerAdapter:AuthenticationManagerBuilder - 覆盖配置方法或自动装配 globalUserDe

无法自动装配字段:私有 org.springframework.security.authentication.AuthenticationManager