* 深入理解SpringSecurity **

本文详细介绍了Spring Security表单认证的配置与实现过程,包括基本原理、自定义用户登录逻辑及个性化认证流程等内容。重点讲解了如何自定义登录页面、成功与失败处理等高级特性。

SpringSecurity 开发基于表单的认证[后面再完善]

一. SpringSecurity的基本原理

1.1 SpringSecurity的开关:

  • 在application.properties中可以设置:
    Security.basic.enabled=false

当注释掉这句的时候,默认开启,如果开启这句话则关闭SpringSecurity身份校验

1.2 SpringSecuirty的默认表单登录自定义实现

  • 新建一个类: src/main/java/BrowserSecurityConfig.java
    @Configuration
    public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
    	@Override
    	protected void configure(HttpSecurity http) throws Exception{
    		//http.formLogin()
    		  http.httpBasic()
    		  .and()
    		  .authorizeReuquests()
    		  .anyRequest()
    		  .authenticated()
    	}}
    

这里是做了一个自定义表单,它是最简单的最基础的,httpBasic是弹窗登录,formLogin是表单登录

1.3 简单原理分析

  • 图示一:
    在这里插入图片描述
  • 图示二:
    在这里插入图片描述
  • 解读:
    • SpringSecurity是由一系列的过滤器链组成
    • 绿色的可以自定义,可以要或者不要,蓝色和红色的部分是一定会存在于SpringSecuirty的拦截链中的,且任何不能改;Exception Translation Filter负责处理FilterSecurity Interceptor中抛出的异常,而FilterSecurity Interceptor是最后一个拦截者(守门员)

1.4 验证功能

  • 处理用户信息获取逻辑接口: UserDetailsService
  • 处理用户校验逻辑: UserDetails
  • 处理密码加密解密: PasswordEncoder

1.5 个性化用户认证流程

  • 自定义登录页面: http.formLogin().loginPage("/imooc-signIn.html")
  • 自定义登录成功处理: AuthenticationSuccessHandler
  • 自定义登录失败处理: AuthenticationFailureHandler

二. 自定义用户登录逻辑

2.1 概述

  • 处理用户信息获取逻辑接口: UserDetailsService
  • 处理用户校验逻辑: UserDetails
  • 处理密码加密解密: PasswordEncoder

2.2 处理用户信息获取逻辑自定义:

@Component
public class MyUserDetailsService Implements UserDetailsService{
	private Logger logger=LoggerFactory.getLogger(getClass());
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
		login.info("登录用户名:"+username);
		//
		return new User(username,"123456",AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));		//自己使用的时候,需要从数据库中读取信息,而不是直接这样简单定义;
	}}

2.3 UserDetails解读:

  • UserDetails封装了登录所需要的所有信息;
  • 方法描述:
    • getAuthorties() 权限信息
    • getPassword() 密码信息
    • getUsername() 用户名信息
    • //下面四个是需要我们自己实现的,如果不需要其中某个方法的功能则可以直接返回true,如果返回false的话则会验证不通过,抛出异常的;
    • isAccountNonExpired 验证账户是否过期 没过期则返回true
    • isCredentialsNonExpired 验证密码是否过期 没过期则返回true
    • isAccountNonLocked() 验证是否被冻结 //冻结可恢复 true表示没被冻结
    • isEnabled() 验证账户是否被删除 //删除不可恢复,一般公司是假删除,这里我们需要查询账户的状态 ture没被删除,所以我们这里要返回true

这里的返回要在上面的代码中return User里面返回,示例:

@Component
public class MyUserDetailsService Implements UserDetailsService{
	private Logger logger=LoggerFactory.getLogger(getClass());
	@Autowired
		private PasswordEncoder passwordEncoder;
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
		login.info("登录用户名:"+username);
		//根据用户名查找用户信息
		return new User(username,passwordEncoder.encode("123456"),
		true,true,true,true,
		AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));		//自己使用的时候,需要从数据库中读取信息,而不是直接这样简单定义;
	}}

2.4 加密解密

  • 路径: org.springframework.security.crypto.password.PasswordEncoder.java
  • PasswrodEncoder中有两个方法,解读:
    • encode(), 它负责将密码加密,当我们注册用户的时候需要调用这个方法将用户密码加密
    • matches(CharSequence rawPassword, String encodePassword),它是由SpringSecurity调用,将用户登录输入的密码与数据库中该用户存储的密码进行比对;前面的是用户输入的密码,后面的是查询出来的密码
    • SpringSecurity每次登陆后加密的密码都是不一样的,它会随机生成盐混在字符串里;然后通过随机生成的盐再解析到固定的密码

2.5 自定义加密

  • 我们需要在@Configuration注解并实现了WebSecurityConfigurerAdapter的接口的类中定Bean:
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
	@Bean
	public PasswordEncoder passwordEncoder(){
		return new BCryptPasswordEncoder();
	}
}
  • 这样就大公告成了,但是有一个小细节需要注意:当启用这个的时候,已经存储在数据库中的用户名匹配的密码必须是加密的,我们需要在当用户注册的时候实现加密逻辑,然后通过上面的验证加密才能使用;如果已经存储的密码没有加密我们可以临时这样解决:[请手动改变]
@Component
public class MyUserDetailsService Implements UserDetailsService{
	private Logger logger=LoggerFactory.getLogger(getClass());
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
		login.info("登录用户名:"+username);
		//
		return new User(username,"123456",
		true,true,true,true,
		AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));		//自己使用的时候,需要从数据库中读取信息,而不是直接这样简单定义;
	}}

三. 个性化用户认证流程

3.1 概述:

  • 自定义登录页面 [登录页面我们自定义]
  • 自定义登录成功处理
  • 自定义登录失败处理

3.2 自定义登录页面:

  • 查找前面已经编写的类:BrowserSecurityConfig.java 中的方法:configure(HttpSecurity http),里面添加自定义登录页面
  • 自定义登录界面:
@Override
protected void cofigure(HttpSecurity http) throws Exception{
	http.formLogin()
		.loginPage("/imooc-signIn.html")		//这里就是自定义了登录页面,我们需要完善这个imooc-signIn.html
		.loginProcessingUrl("/authentication/form")		//这里我们需要自定义表单登录的路径,因为Security默认的路径是login,Post  我们需要重写后才能使表单登录的请求生效,校验用户的代码才能执行
		.and()
		.csrf().disable() 		//关闭跨站请求伪造防护,先暂时关闭掉,这样才能让我们简单的登录页面生效;
		.authorizeRequests()
		.antMatchers("/imooc-signIn.html").permitAll()		//让登录页面不需要身份认证,否则其他页面也会跳转到这个页面,这个页面也会跳转到这个页面,陷入死循环
		.anyRequest()
		.authenticated();
}
  • 表单主要代码图示:
    在这里插入图片描述

3.3 优化

  • 我们这样只是完成了一个简单的认证登录页面,我们需要优化一下功能,图示:
    在这里插入图片描述
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗余

码字来之不易,您的鼓励我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值