为自定义userdetailsservice定义bean[英] defining bean for custom userdetailsservice

问题描述

如何定义我的自定义 UserDetailsService bean,使我的 spring mvc web 应用程序能够使用我的底层 MySQL 数据库来检查用户和密码的身份验证?

以下是具体内容:

我正在向 spring petclinic 示例添加安全性,作为了解 Spring 安全性的一种方式.我正在使用 Java 配置,并设置了一个扩展 WebSecurityConfigurerAdapter 的 SecurityConfig.java 文件.我正在尝试以一种利用由宠物诊所示例中内置的 ClinicService 工具管理的 MySQL 数据库的方式设置 JdbcAuthentication.因此,我创建了一个扩展 UserDetailsService 的 CustomUserDetailsService 类,旨在将 SecurityConfig.java 与 ClinicService.java 链接起来.我创建了一个 User 类和一个 Role 类来分别对 MySQL 数据库中的 users 和 roles 表进行建模.

然后我在 business-config.xml 中添加以下行来定义 CustomUserDetailService:

<bean class="org.springframework.samples.petclinic.service.CustomUserDetailsService"></bean>

但我仍然收到以下错误,说明 CustomUserDetailService 的 bean 尚未定义:

Caused by: java.lang.IllegalArgumentException: Can not set  
org.springframework.samples.petclinic.service.CustomUserDetailsService field  
org.springframework.security.samples.petclinic.config.SecurityConfig.myCustomUserDetailsService  
to $Proxy61

为了保持这篇文章的简洁,我已将相关的备份材料加载到一个文件共享站点.您可以通过单击以下链接阅读所有源代码和完整的堆栈跟踪:

您可以阅读SecurityConfig.java 点击此链接.
business-config.xml 的代码是 在此链接.
CustomUserDetailService.java 的代码是 在此链接.
User 实体的代码是在此链接.
Role 实体的代码是在此链接.
在此链接可以阅读完整的堆栈跟踪.

应用程序的所有其他代码都可以在 Spring petclinic 示例的 github 页面上找到,您可以阅读 点击此链接.

这里是login.jsp 代码链接.

这里是我修改后的 business-config.xml 代码的链接.p>

推荐答案

总结评论,这里是答案.

这里有几个问题:

1) 在 Spring 中混合 XML 配置和 Java 配置时,将 java 配置导入到 xml 配置文件中,<context:annotation-config/> 需要存在于 xml 文件中,并且需要将 java 配置类声明为 bean.<context:annotation-config/> 将启用已声明 bean 的注释处理,然后将处理 @Configuration 注释.在文档中阅读更多内容:http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-java-combining

要解决问题,请在 business-config.xml 中插入 <context:annotation-config/>.<bean class="org.springframework.security.samples.petclinic.config.SecurityConfig"></bean> 需要 <context:annotation-config/> 才能工作,因此它们需要在同一个 bean 配置文件中声明.

2) 您在 SpringConfig 中自动装配一个具体类 (CustomUserDetailsS​​erivce) 而不是接口 (UserDetailsS​​ervice).虽然可以使用 Spring 自动装配具体类,但通常最好自动装配到接口(Spring 将自动装配自定义用户详细信息服务实现到 @Autowired UserDetailsS​​ervice 字段).Spring 围绕有线类创建代理以启用某些功能(例如声明性事务),并且此类代理在自动装配时可以轻松实现接口,但如果尝试自动装配到具体类则可能会失败.虽然有可能实现它 - 更多信息在这里:Spring Autowiring 类与接口?在这种情况下,自动装配到 UserDetailsS​​ervice 接口肯定会更好,因为这是我们的安全配置实际依赖的.

要解决此问题,请在 SpringConfig 中将字段类型指定为 UserDetailsS​​ervice:

//Use UseDetailsService interface as field type instead of concrete class CustomUserDao
@Autowired
private UserDetailsService myCustomUserDetailsService;

3) 您似乎正在使用自定义用户详细信息服务设置 jdbc 身份验证和身份验证.如果您希望 Spring Security 使用 jdbc 查询数据库并查找现有用户及其角色等,通常使用 Spring JDBC 身份验证...如果您想实现对用户/角色等的查询,则使用自定义 UserDetailsS​​erivce ......您自己.在您的示例中(因为您提供了将使用 ClinicService 查询后端的自定义 UserDetailsS​​ervice),您不需要 JDBC 身份验证.

这是一个通过 java config 使用自定义 UserDetailsS​​ervice(在别处实现并由 spring 自动装配)的工作 spring 安全配置示例:

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/petclinic/")
                .usernameParameter("j_username") // default is username
                .passwordParameter("j_password") // default is password
                .loginProcessingUrl("/j_spring_security_check") // default is /login with an HTTP post 
                .failureUrl("/login")
                .permitAll()
                .and()
            .logout()
                .logoutSuccessUrl("/index.jsp")
                .and()
            .authorizeRequests()
                .antMatchers("/**").hasRole("ROLE_ADMIN")
                .antMatchers("/j_spring_security_check").permitAll()
                .and()
            .userDetailsService(userDetailsService);
    }
}

我建议阅读实际文档,因为它描述了特定的配置构建器方法的作用并提供了示例:http://docs.spring.io/spring-security/site/docs/3.2.0.RC2/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html#formLogin()

EDIT 1 - 添加登录表单配置和文档链接

编辑 2 - 为问题 1) 添加了更多解释

编辑 3 - 将角色名称从"ADMIN"更改为"ROLE_ADMiN"以匹配 UserDetailsS​​ervice 中的角色名称

本文地址:https://www.itbaoku.cn/post/978573.html