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

查看:1209
本文介绍了为自定义userdetails服务定义bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I define my custom UserDetailsService bean in a way that enables my spring mvc web app to use my underlying MySQL database to check authentication for users and passwords?

以下是具体细节:

我正在为<$ c $添加安全性c> spring petclinic 样本作为了解春季安全的一种方式。我正在使用Java配置,并设置了 SecurityConfig.java 文件,该文件扩展了 WebSecurityConfigurerAdapter 。我试图以一种利用由内置的 ClinicService 工具管理的MySQL数据库的方式设置 JdbcAuthentication petclinic样本。因此,我创建了一个 CustomUserDetailsS​​ervice 类,它扩展了 UserDetailsS​​ervice ,并且打算链接 SecurityConfig .java with ClinicService.java 。我创建了一个用户类和一个 Role 类来模拟用户 roles 表。

I am adding security to the spring petclinic sample as a way of learning about spring security. I am using Java configuration, and have set up a SecurityConfig.java file which extends WebSecurityConfigurerAdapter. I am trying to set up JdbcAuthentication in a way that utilizes a MySQL database managed by the ClinicService tools that are built into the petclinic sample. I therefore created a CustomUserDetailsService class which extends UserDetailsService, and which is intented to link the SecurityConfig.java with ClinicService.java. I created a User class and a Role class to model the users and roles tables in the MySQL database, respectively.

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

I then added the following line to business-config.xml to define the CustomUserDetailService:

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

但是我仍然收到以下错误,指出 CustomUserDetailService的bean 尚未定义:

But yet I am still getting the following error stating that the bean for CustomUserDetailService has not been defined:

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 的代码是在此链接

用户实体的代码是在此链接

角色的代码实体此链接

完整的堆栈跟踪可以在此链接中阅读。

You can read SecurityConfig.java by clicking on this link.
The code for business-config.xml is at this link.
The code for CustomUserDetailService.java is at this link.
The code for the User entity is at this link.
The code for the Role entity is at this link.
The complete stack trace can be read at this link.

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

All of the other code for the application can be found at the github page for the Spring petclinic sample, which you can read by clicking on this link.

这是 login.jsp代码的链接

这是我修改后的业务的链接-config.xml代码

推荐答案

总结评论,这是答案。

这里有几个问题:

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

1) When mixing XML configuration and Java configuration in Spring in a way that java config is imported inside xml config file, <context:annotation-config/> needs to be present in xml file and java config class needs to be declared as a bean. <context:annotation-config/> will enable annotation processing of the declared bean and @Configuration annotation will then be processed. Read more at the documentation: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-java-combining

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

To fix te problem insert <context:annotation-config/> in business-config.xml. <context:annotation-config/> is needed for <bean class="org.springframework.security.samples.petclinic.config.SecurityConfig"></bean> to work so they need to be declared in the same bean profile.

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

2) You are autowiring a concrete class (CustomUserDetailsSerivce) in SpringConfig instead of an interface (UserDetailsService). While it's possible to use Spring to autowire concrete classes usually it's better to autowire to interfaces (Spring will autowire concreate CustomUserDetailsSerivce implementation to @Autowired UserDetailsService field). Spring creates proxies around wired classes to enable certain features (such as declarative transactions) and such proxies may easily implement an interface when autowiring but may fail if attempted to be autowired to a concrete class. It is possible though to achieve it - more information here: Spring Autowiring class vs. interface? In this case, it's definitely better to autowire to UserDetailsService interface since that is what our security config actually depends on.

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

To fix this issue specify field type as UserDetailsService in SpringConfig:

//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身份验证。

3) You seem to be setting up both jdbc authentication and authentication using a custom user details service. Spring JDBC authentication is usually used if you want Spring Security to use jdbc to query a database and find about existing users and their roles etc... Custom UserDetailsSerivce is used if you want implement querying for users/roles etc... your self. In your example (since you are providing your custom UserDetailsService which will query the backend using ClinicService) you don't need JDBC authentication.

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

Here's an example of working spring security configuration that uses custom UserDetailsService (implemented elsewhere and autowired by spring) via java config:

@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()

I suggest reading the actual documentation as it describes what specific configuration builder methods do and provide the examples: http://docs.spring.io/spring-security/site/docs/3.2.0.RC2/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html#formLogin()

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

EDIT 1 - added login form configuration and link to documentation

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

EDIT 2 - added more explanations for problem 1)

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

EDIT 3 - changed role name form "ADMIN" to "ROLE_ADMiN" to match role names in UserDetailsService

这篇关于为自定义userdetails服务定义bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆