深入Spring Security魔幻山谷-获取认证机制核心原理讲解(新版)

本文基于Springboot+Vue+Spring Security框架而写的原创学习笔记,demo代码参考《Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统》一书。

这是一个古老的传说。

在神秘的Web系统世界里,有一座名为Spring Security的山谷,它高耸入云,蔓延千里,鸟飞不过,兽攀不了。这座山谷只有一条逼仄的道路可通。然而,若要通过这条道路前往另一头的世界,就必须先拿到一块名为token的令牌,只有这样,道路上戍守关口的士兵才会放行。

img

想要获得这块token令牌,必须带着一把有用的userName钥匙和password密码,进入到山谷深处,找到藏匿宝箱的山洞(数据库),若能用钥匙打开其中一个宝箱,就证明这把userName钥匙是有用的。正常情况下,宝箱里会有一块记录各种信息的木牌,包含着钥匙名和密码,其密码只有与你所携带的密码检验一致时,才能继续往前走,得到的通行信息将会在下一个关口处做认证,进而在道路尽头处的JWT魔法屋里获得加密的token令牌。

慢着,既然山谷关口处有士兵戍守,令牌又在山谷当中,在还没有获得令牌的情况下,又怎么能进入呢?

设置关口的军官早已想到这种情况,因此,他特意设置了一条自行命名为“login”的道路,没有令牌的外来人员可从这条道路进入山谷,去寻找传说中的token令牌。这条道路仅仅只能进入到山谷,却无法通过山谷到达另一头的世界,因此,它更像是一条专门为了给外来人员获取token令牌而开辟出来的道路。

img

这一路上会有各种关口被士兵把守检查,只有都一一通过了,才能继续往前走,路上会遇到一位名为ProviderManager的管理员,他管理着所有信息提供者Provider......需找到一位可正确带路的信息提供者Provider,在他的引导下,前往山洞(数据库),成功获取到宝箱,拿到里面记录信息的木牌,这样方能验证所携带的username和password是否正确。若都正确,那么接下来就可将信息进行认证,并前往JWT魔法屋获取token令牌。最后携带着token返回到家乡,让族人都可穿过山谷而进入到web系统,去获取更多珍贵的资源。

这就是整个security的游戏规则原理。

那么,在游戏开始之前,我们先了解下当年戍守山谷的军官是如何设置这道权限关口的......

关口的自定义设置主要有三部分:通过钥匙username获取到宝箱;宝箱里的UserDetails通行信息设置;关口通行过往检查SecurityConfig设置。

1.宝箱里的通行信息:

1 /** 2 * 安全用户模型 3 * 4 * @author zhujiqian 5 * @date 2020/7/30 15:27 6 */ 7 public class JwtUserDetails implements UserDetails { 8 private static final long serialVersionUID = 1L; 9 10 private String username; 11 private String password; 12 private String salt; 13 private Collection<? extends GrantedAuthority> authorities; 14 15 JwtUserDetails(String username, String password, String salt, Collection<? extends GrantedAuthority> authorities) { 16 this.username = username; 17 this.password = password; 18 this.salt = salt; 19 this.authorities = authorities; 20 } 21 22 @Override 23 public String getUsername() { 24 return username; 25 } 26 27 @JsonIgnore 28 @Override 29 public String getPassword() { 30 return password; 31 } 32 33 public String getSalt() { 34 return salt; 35 } 36 37 @Override 38 public Collection<? extends GrantedAuthority> getAuthorities() { 39 return authorities; 40 } 41 42 @JsonIgnore 43 @Override 44 public boolean isAccountNonExpired() { 45 return true; 46 } 47 48 @JsonIgnore 49 @Override 50 public boolean isAccountNonLocked() { 51 return true; 52 } 53 54 @JsonIgnore 55 @Override 56 public boolean isCredentialsNonExpired() { 57 return true; 58 } 59 60 @JsonIgnore 61 @Override 62 public boolean isEnabled() { 63 return true; 64 } 65 66 }

这里JwtUserDetails实现Spring Security 里的UserDetails类,这个类是长这样的,下面对各个字段做了注释:

1 public interface UserDetails extends Serializable { 2 /** 3 *用户权限集,默认需要添加ROLE_前缀 4 */ 5 Collection<? extends GrantedAuthority> getAuthorities(); 6 7 /** 8 *用户的加密密码,不加密会使用{noop}前缀 9 */ 10 String getPassword(); 11 12 /** 13 *获取应用里唯一用户名 14 */ 15 String getUsername(); 16 17 /** 18 *检查账户是否过期 19 */ 20 boolean isAccountNonExpired(); 21 22 /** 23 *检查账户是否锁定 24 */ 25 boolean isAccountNonLocked(); 26 27 /** 28 *检查凭证是否过期 29 */ 30 boolean isCredentialsNonExpired(); 31 32 /** 33 *检查账户是否可用 34 */ 35 boolean isEnabled(); 36 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppfxf.html