spring security 5 (3)-UserDetails用户详情

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangb_java/article/details/86579694

用户登录时,系统会根据用户名,从存储设备查找该用户的密码及权限等,将其组装成一个UserDetails对象。并用UserDetails中的数据对用户进行认证,决定其输入的用户名/密码是否正确。

从内存认证

  • 之前两篇我使用的是预置的user用户,以下则自定义一个user用户,密码123,权限是auth。user用户登录时会根据这些信息自动构建一个UserDetails,保存在内存中。
  • passwordEncoder:这里设置密码不加密,5.0以后必须配置这一项,否则报错,具体以后再讲。
@SpringBootConfiguration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	public void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth
			.inMemoryAuthentication()//用户详细存储在内存
				.withUser("user").password("123").authorities("auth")//创建一个用户
				.and()
			.passwordEncoder(NoOpPasswordEncoder.getInstance());//不加密

从数据库认证

	@Autowired
	DataSource dataSource;
	
	public void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.jdbcAuthentication().dataSource(dataSource)//使用jdbc默认sql
			.passwordEncoder(NoOpPasswordEncoder.getInstance());

此时用户登录,会从数据库读取相关用户/密码/权限等信息,默认会执行系统内置的两条sql,如下

自定义sql

内置的sql不一定能和我们的数据库匹配,以下方式可自定义sql,这两条sql就是上面系统默认的,

	@Autowired
	DataSource dataSource;
	
	public void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.jdbcAuthentication().dataSource(dataSource)
			.usersByUsernameQuery("select username,password,enabled from users where username = ?")
			.authoritiesByUsernameQuery("select username,authority from authorities where username = ?")
			.passwordEncoder(NoOpPasswordEncoder.getInstance());
  • usersByUsernameQuery:根据登录时输入的用户名查询用户名/密码,enabled是用户激活状态true/false。
  • authoritiesByUsernameQuery:查询用户名/权限,可以查出多条结果,表示用户有多个权限。具体sql怎么写要看你的数据库结构,只要关键字段名能够对应上就行了。之后系统就会根据查询结果集自动构建UserDetails。

UserDetails源码

包含用户名、密码、权限以及四个状态,状态默认为true,其中任何一个为false,都将导致登录失败。

public interface UserDetails extends Serializable {
	Collection<? extends GrantedAuthority> getAuthorities();//权限 
	String getPassword();    //密码
	String getUsername();    //用户名

	boolean isAccountNonExpired();   //账号是否未过期
	boolean isAccountNonLocked();    //账号是否未锁定
	boolean isCredentialsNonExpired();//密码是否未过期
	boolean isEnabled();        //是否激活

自定义UserDetails

可以从任意数据库,甚至缓存等,自由构建UserDetails,需要编写自己的UserDetailsService。

	public void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService())//自定义构建
			.passwordEncoder(NoOpPasswordEncoder.getInstance());
	}
	
	@Bean
	public UserDetailsService userDetailsService(){
		return new UserDetailsService() {
			//username是用户登录时填的用户名
			public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
				//根据username查询密码,现假设是user登录,从任意数据库查到密码是123
				String password = "123";
                                //如果查不到用户名,这里可以抛出UsernameNotFoundException异常
				//根据username查询权限,这里假设从任意位置查到权限是auth
				List<GrantedAuthority> authorities= new ArrayList<GrantedAuthority>();
				authorities.add(new SimpleGrantedAuthority("auth"));
				//User是系统自带的UserDetails实现类,4个状态其中一个为false就会抛异常	
			        return new User(username, password, true, true, true, true, authorities);			
                        }
		};
	}

猜你喜欢

转载自blog.csdn.net/wangb_java/article/details/86579694
今日推荐