文章目录
- 一、SpringSecurity简介
- 二、常用类详解
- 三、自定义登录逻辑(前后端一体)
- 四、授权
- 五、CSRF
- 六、Oauth2认证
- 七、SpringSecurity 与Oauth2的整合
- 八、SpringSecurity Oauth2整合JWT
- 九、SpringSecurity Oauth2整合单点登录(SSO)
一、SpringSecurity简介
SpringSecurity是一个功能强大的、可高度定制的身份验证和访问控制的框架。常用的此类安全框架还有Apache Shiro.
- 用户认证(Authentication):验证某个用户能否访问该系统即能否登录,需要用户提供用户名和密码。
- 用户授权(Authorization):指用户是否有权限执行某个操作,一般来说系统会为不同的用户分配不同的角色,而不同的角色对应一系列权限。
二、常用类详解
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
1、UserDetailsService
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
2、UserDetails
public interface UserDetails extends Serializable {
//获取用户权限,不能返回空
Collection<? extends GrantedAuthority> getAuthorities();
//获取用户密码
String getPassword();
//获取用户名
String getUsername();
//判断用户是否未过期,过期的账号不能被认证
boolean isAccountNonExpired();
//账户是否未被锁定
boolean isAccountNonLocked();
//凭证(密码)是否未过期
boolean isCredentialsNonExpired();
//用户是否被启用
boolean isEnabled();
}
3、UserDetails实现类User
public class User implements UserDetails, CredentialsContainer {
private static final long serialVersionUID = 550L;
private static final Log logger = LogFactory.getLog(User.class);
private String password;
private final String username;
private final Set<GrantedAuthority> authorities;
private final boolean accountNonExpired;
private final boolean accountNonLocked;
private final boolean credentialsNonExpired;
private final boolean enabled;
public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
this(username, password, true, true, true, true, authorities);
}
public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
Assert.isTrue(username != null && !"".equals(username) && password != null, "Cannot pass null or empty values to constructor");
this.username = username;
this.password = password;
this.enabled = enabled;
this.accountNonExpired = accountNonExpired;
this.credentialsNonExpired = credentialsNonExpired;
this.accountNonLocked = accountNonLocked;
this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities));
}
public Collection<GrantedAuthority> getAuthorities() {
return this.authorities;
}
public String getPassword() {
return this.password;
}
public String getUsername() {
return this.username;
}
public boolean isEnabled() {
return this.enabled;
}
......
}
4、密码解析器PasswordEncoder
public interface PasswordEncoder {
/**
加密明文密码
rawPassword:明文密码
return:加密后的密码
*/
String encode(CharSequence rawPassword);
/**
匹配
rawPassword:客户端传输的明文密码
encodedPassword:数据库保存的加密后的密码
*/
boolean matches(CharSequence rawPassword, String encodedPassword);
/**
二次加密
*/
default boolean upgradeEncoding(String encodedPassword) {
return false;
}
}
5、PasswordEncoder实现类BCryptPasswordEncoder
BCryptPasswordEncoder是官方推荐的密码解析器,BCryptPasswordEncoder是对bcrypt强散列方法的具体实现,是基于hash算法实现的单向加密,可以通过strength控制加密强度,默认长度是10。
public class BCryptPasswordEncoder implements PasswordEncoder {
private Pattern BCRYPT_PATTERN;
private final Log logger;
private final int strength;//密码长度
private final BCryptPasswordEncoder.BCryptVersion version;
private final SecureRandom random;
public String encode(CharSequence rawPassword) {
if (rawPassword == null) {
throw new IllegalArgumentException("rawPassword cannot be null");
} else {
String salt = this.getSalt();
return BCrypt.hashpw(rawPassword.toString(), salt);
}
}
private String getSalt() {
return this.random != null ? BCrypt.gensalt(this.version.getVersion(), this.strength, this.random) : BCrypt.gensalt(this.version.getVersion(), this.strength);
}
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (rawPassword == null) {
throw new IllegalArgumentException("rawPassword cannot be null");
} else if (encodedPassword != null && encodedPassword.length() != 0) {