`

spring-security(十四)UserDetailsService

阅读更多
前言:
  作为spring security的核心类,大多数的认证方式都会用到UserDetailsService和UserDetails这两个接口,本文会详细探讨下UserDetailsService及其实现类。

1. UserDetailsService接口
在spring security中,为了方便扩展,UserDetailsService接口被设计的极其简单,只包含一个方法
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

根据提供的用户名,查找对应的用户信息,只是查找信息,没有和认证相关的任何逻辑,是DaoAuthenticationProvider默认使用的用户信息加在类,返回的UserDetails也是一个接口。根据具体实现的不同,做用户信息查找时即有可能是大小写敏感,也有可能不敏感,所以UserDetails中的用户名并不一定和传入的用户名一致。在一些认证方式中,即便他们并不真的使用用户名和密码,也会用到UserDetailsService类,可能仅仅是想利用UserDetails对象中的GrantedAuthority信息来做权限判断(如LDAP、X.509、CAS等,这些认证系统自身承担着验证证书是否有效的任务)。
因为UserDetailsService接口是如此简单,我们很容易实现他,来自定义我们获取用户信息的逻辑,同时spring security也为我们提供了一些基本常见的实现。
2.基于内存的认证
自定义UserDetailsService从我们喜欢的一种数据持久化引擎中(文件、数据库等)获取数据并不麻烦,但有时候我们并不需要这么复杂的实现,例如我们仅仅是做一个spring security的原型、或者是在学习spring security,你并不想花时间来搭建一个数据库,此时就可以以使用基于内存的用户信息存储,使用java config配置用户信息如下:
	@Bean
	public UserDetailsService userDetailsService() {
		InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
		manager.createUser(User.withUsername("user").password("password").roles("USER").build());
		manager.createUser(User.withUsername("admin").password("password").roles("ADMIN").build());
		return manager;
	}

这种方式还支持properties文件来配置
@Bean
	public UserDetailsService userDetailsService() throws FileNotFoundException, IOException {

		Properties properties = new Properties();
		properties.load(getClass().getClassLoader().getResourceAsStream("users.properties"));

		return new InMemoryUserDetailsManager(properties);
	}

properties的文件格式如下:
username=password,grantedAuthority[,grantedAuthority][,enabled|disabled]

例如
 
jimi=jimispassword,ROLE_USER,ROLE_ADMIN,enabled
bob=bobspassword,ROLE_USER,enabled

还可以使用如下代码段来创建
@Autowired
	public void auth(AuthenticationManagerBuilder auth) throws Exception {
		auth.inMemoryAuthentication()
				.withUser("admin").password("password").authorities("ROLE_ADMIN").and()
				.withUser("user").password("password").authorities("ROLE_USER");
	}

3.基于关系数据库的认证
3.1 spring security也为我们提供了一个从关系型数据库获取认证信息的实现-JdbcDaoImpl,在这个类内部使用了Spring JDBC,下面是一个具体使用的配置例子
@Bean
	public DruidDataSource dataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUsername("root");
		dataSource.setPassword("sso");
		dataSource.setName("chengf");
		dataSource.setUrl("jdbc:mysql://localhost:3306/chengf?useUnicode=true&characterEncoding=UTF-8");
		dataSource.setMaxActive(20);
		dataSource.setInitialSize(1);
		dataSource.setMaxWait(60000);
		dataSource.setMinIdle(1);
		dataSource.setTimeBetweenEvictionRunsMillis(60000);
		dataSource.setMinEvictableIdleTimeMillis(300000);
		dataSource.setValidationQuery("select 'x'");
		dataSource.setPoolPreparedStatements(true);
		dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
		return dataSource;
	}

	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
		auth.jdbcAuthentication().dataSource(dataSource);
	}

完整的例子请参考spring-security(四)java config-sample之jdbc
3.2 默认情况下,JdbcDaoImpl直接从数据库中获取某个特定用户对应的权限列表信息,在实际应用中我们可能会先将用户分组,再把具体的权限赋予某个分组,从而使这个组里面的用户都具有这些权限,JdbcDaoImpl也为我们提供了 分组的支持,默认情况下没有启用,如果想使用这个功能,可以通过如下设置
@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
		auth.jdbcAuthentication().dataSource(dataSource).getUserDetailsService().setEnableGroups(true);;
	}

如果spring 默认的schema不能满足我们的业务需求(表结构的定义、信息的完整性),我们也可以利用JdbcDaoImpl,重写其中的查询语句,如我们想重写查询用户信息的语句可以如下配置
@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
		auth.jdbcAuthentication().dataSource(dataSource).getUserDetailsService().setEnableGroups(true);;
		auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery("select username,password,email,phone,address,enabled from my_user_table where username = ? ");
	}

如果默认实现和我们需求相差太大,简单修改配置已不能满足我们需求,我们可以自己实现加载用户信息的类,就是实现UserDetailsService,并把他作为bean注册到spring 中即可。

@Bean
	public DruidDataSource dataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUsername("root");
		dataSource.setPassword("sso");
		dataSource.setName("chengf");
		dataSource.setUrl("jdbc:mysql://localhost:3306/chengf?useUnicode=true&characterEncoding=UTF-8");
		dataSource.setMaxActive(20);
		return dataSource;
	}
	@Bean
	public UserDetailsService userDetailsService () {
		MyUserDetailsService userDetailsService = new MyUserDetailsService();
		userDetailsService.setDataSource(dataSource());
		return userDetailsService;
	}

这样在程序启动时,配置类InitializeUserDetailsManagerConfigurer加载时,会为我们创建一个DaoAuthenticationProvider,并且使用我们定义的UserDetailsService。具体过程可参考
spring-security(二)java config加载机制-@EnableGlobalAuthentication
分享到:
评论

相关推荐

    spring-security-oauth2源码

    Spring Security OAuth2允许开发者自定义各种组件,如TokenEnhancer(增强令牌)、UserDetailsService(用户详情服务)等,以满足特定需求。 6. **spring-security-oauth-master** 文件夹中可能包含的内容: - 源...

    spring-security源代码

    Spring Security 是一个强大的安全框架,主要用于Java应用的安全管理。它提供了认证、授权、访问控制以及CSRF防护等核心功能,广泛应用于Web应用和企业级系统。这个压缩包文件"spring-security-parent-2.0.4"是...

    spring-security-oauth2-authorization-server.zip

    本项目“spring-security-oauth2-authorization-server”将带你深入理解如何利用Spring Security OAuth2构建一个授权服务器,以保护你的API并提供安全的访问控制。 OAuth2是一种开放标准,用于授权第三方应用访问...

    spring-security-material-master.zip

    Spring Security 是一个强大的安全框架,主要用于Java web应用的安全管理。在Spring Boot中,Spring Security 提供了一种简单而有效的方式来保护应用程序,防止未经授权的访问。本资料“spring-security-material-...

    Spring-Security-Demo-master.zip

    《Spring Security与Spring Boot整合实操详解》 在IT领域,Spring Security和Spring Boot是两个极为重要的组件,它们为开发者提供了强大的安全管理和应用程序构建能力。本篇将详细讲解如何将Spring Security集成到...

    spring-security-ldap-2.0.1

    3. UserDetailsService:Spring Security的核心接口,用于处理用户认证。当使用LDAP时,可以实现这个接口,从LDAP目录中检索用户信息。 三、配置Spring Security LDAP 1. 配置ContextSource:在Spring Security的...

    spring-boot与spring-security整合的java代码

    为了实现用户认证,Spring Security提供了一种基于内存的用户存储方式,可以通过`UserDetailsService`接口实现。例如: ```java @Service public class UserDetailsServiceImpl implements UserDetailsService { ...

    spring-cloud-security例子

    《Spring Cloud Security实战详解》 在微服务架构中,安全问题尤为重要,而Spring Cloud Security作为Spring Cloud生态的一部分,为开发者提供了强大的安全管理和身份验证功能。本文将深入探讨Spring Cloud ...

    spring-security 官方文档 中文版

    #### 四、Spring Security 社区 - **4.1 任务跟踪**:开发者可以通过 JIRA 等工具跟踪项目的问题和进展。 - **4.2 成为参与者**:鼓励社区成员贡献代码、提出建议等。 - **4.3 更多信息**:提供了更多关于 Spring ...

    spring-security-2.0.6. API和 jar包

    Spring Security 是一个强大的Java框架,用于为Web应用和企业级应用提供安全控制。它提供了全面的身份验证、授权和访问控制功能。在这个版本2.0.6中,我们关注的是其API文档和对应的JAR包。 首先,让我们深入了解...

    spring-security-3.0.3 jar包( 含源码)

    Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架,用于Java应用程序。这个压缩包包含的是Spring Security 3.0.3版本的jar文件,同时提供了源代码,这对于开发者来说是一个宝贵的资源,可以深入...

    spring-security文档和jar包

    学习Spring Security时,需要理解其核心组件如AuthenticationManager、UserDetailsService、AccessDecisionManager等,并熟悉XML或Java配置方式来定制安全行为。同时,实践编写安全拦截器、自定义过滤器以及处理异常...

    spring-security-oauth2

    - 集成用户认证机制,如Spring Security的UserDetailsService。 - 编写客户端应用,实现令牌的获取和使用。 5. 扩展与优化 - 使用JWT(JSON Web Tokens)作为令牌,以减少服务器之间的通信成本。 - 配置刷新...

    spring-security-helloworld

    【标题】"spring-security-helloworld" 是一个基于Spring Security框架的简单示例项目,它用于初学者理解并实践Spring Security的基础用法。Spring Security是一个强大的安全框架,为Java应用程序提供了全面的安全...

    spring-security-2.0.5.jar2

    《Spring Security 2.0.5.jar:深度解析与实战指南》 在Java Web开发领域,Spring Security是一款不可或缺的安全框架,它为应用提供了强大的身份验证和授权功能。本篇文章将聚焦于Spring Security 2.0.5版本,通过...

    spring-security-3.1.0.RELEASE

    《Spring Security 3.1.0.RELEASE:企业级安全框架深度解析》 Spring Security是Java平台上广泛使用的安全框架,其3.1.0.RELEASE版本是该框架的一个重要里程碑,为开发者提供了全面的安全控制,从Web应用到企业级...

    spring-security-3.1.0.RELEASE.zip

    Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架,用于保护基于Java的Web应用程序。它是Spring生态系统的一部分,旨在无缝集成到Spring应用程序中,提供一套全面的安全解决方案。Spring Security...

    spring-security-3.1.0.RC3

    《Spring Security 3.1.0.RC3:企业级安全框架详解》 Spring Security是Java平台上广泛使用的安全框架,其3.1.0.RC3版本为开发者提供了强大而灵活的安全控制,使得构建安全的Web应用变得简单易行。本篇文章将深入...

    spring-security-core-2.0.6.RELEASE

    《Spring Security核心模块详解——基于2.0.6.RELEASE版本》 在Java Web开发领域,Spring Security是一款广泛使用的安全框架,它为应用程序提供了全面的安全管理解决方案,包括身份验证、授权以及会话管理等关键...

    Spring-Security_java_

    **Spring Security 概述** Spring Security 是一个强大的且高度可定制的身份验证和访问控制框架,专为 Java 应用程序设计。它旨在提供全面的安全解决方案,包括 Web 应用程序和 RESTful API 的保护。Spring ...

Global site tag (gtag.js) - Google Analytics