为自定义userdetails服务定义bean

时间:2014-03-30 21:41:15

标签: java spring spring-mvc spring-security

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

以下是具体细节:

我正在为spring petclinic示例添加安全性,以此作为了解弹簧安全性的一种方式。我正在使用Java配置,并设置了扩展SecurityConfig.java的{​​{1}}文件。我试图以一种利用由petclinic样本中内置的WebSecurityConfigurerAdapter工具管理的MySQL数据库的方式设置JdbcAuthentication。因此,我创建了一个ClinicService类,其范围为CustomUserDetailsService,旨在将UserDetailsServiceSecurityConfig.java相关联。我创建了一个ClinicService.java类和一个User类来分别为MySQL数据库中的Roleusers表建模。

然后我将以下行添加到roles以定义business-config.xml

CustomUserDetailService

但是我仍然收到以下错误,指出<bean class="org.springframework.samples.petclinic.service.CustomUserDetailsService"></bean> 的bean尚未定义:

CustomUserDetailService

为了简化此帖子,我已将相关备份资料加载到文件共享网站。您可以通过单击以下链接阅读所有源代码和完整堆栈跟踪:

您可以阅读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 by clicking on this link SecurityConfig.java的代码为at this link business-config.xml的代码为at this link CustomUserDetailService.java实体的代码为at this link User实体的代码为at this link 可以读取完整的堆栈跟踪at this link

应用程序的所有其他代码都可以在Spring petclinic样本的github页面找到,您可以阅读by clicking on this link

这是a link to the code for login.jsp

这是a link to my revised business-config.xml code

1 个答案:

答案 0 :(得分:4)

总结评论,这里是答案。

这里有几个问题:

1)在Spring中混合XML配置和Java配置的方式是在xml配置文件中导入java配置时,<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

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

2)您正在SpringConfig中自动装配一个具体类(CustomUserDetailsS​​erivce)而不是一个接口(UserDetailsS​​ervice)。虽然可以使用Spring自动装配具体类,但通常最好自动连接到接口(Spring将自动装配将CustomUserDetailsS​​erivce实现与@Autowired UserDetailsS​​ervice字段相结合)。 Spring在有线类周围创建代理以启用某些功能(例如声明式事务),并且此类代理可以在自动装配时轻松实现接口,但如果尝试自动连接到具体类,则可能会失败。虽然有可能实现它 - 更多信息在这里:Spring Autowiring class vs. interface? 在这种情况下,自动连接到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。在您的示例中(因为您提供的自定义UserDetailsS​​ervice将使用ClinicService查询后端),您不需要JDBC身份验证。

以下是使用自定义UserDetailsS​​ervice(通过其他地方实现并由spring自动装配)通过java config实现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()

编辑1 - 添加了登录表单配置并链接到文档

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

编辑3 - 更改了角色名称表格&#34; ADMIN&#34;到&#34; ROLE_ADMiN&#34;匹配UserDetailsS​​ervice中的角色名称