一、WebSecurityConfigurerAdapter 总配置类:
1、介绍:配置类
2、主要方法:
(1)configure(HttpSecurity http)
protected void configure(HttpSecurity http) throws Exception {
this.logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");
((HttpSecurity)((HttpSecurity)((AuthorizedUrl)http.authorizeRequests().anyRequest()).authenticated().and()).formLogin().and()).httpBasic();
}
?可以看到 WebSecurityConfigurerAdapter 已经默认声明了一些安全特性:
? ① 验证所有用户请求;
? ②?允许用户使用表单登录进行身份验证(Spring Security 提供了一个简单的表单登录页面);
? ③?允许用户使用 HTTP 基本认证。
3、使用方法:自定义一个类如WebSecurityConfig?继承WebSecurityConfigurerAdapter抽象类,WebSecurityConfig?类上加上?@EnableWebSecurity?注解后,便会自动被?Spring?发现并注册(点击?@EnableWebSecurity?注解可以看到?@Configuration?注解已经存在,所以此处不需要额外添加)。
二、HttpSecurity:
1、作用:??HttpSecurity?实际上对应了?Spring Security?命名空间配置方式中?xml?文件内的标签。允许我们为特定的?http?请求配置安全策略。HttpSecurity?首先被设计为链式调用,在执行每个方法后,都会返回一个预期的上下文,便于连续调用,除非使用?and()?方法结束当前标签,上下文才会回到?HttpSecurity?,否则链式调用的上下文将自动进入对应的标签域。
2、主要方法:?HttpSecurity?提供了很多配置相关的方法,分别对应命名空间配置中的子标签?<http>,如:
(1)authorizeRequests():对应?<intercept-url>标签,该方法实际上返回了一个?URL?拦截注册器,我们可以调用它提供的?anyRequest()、antMatchers()?和?regexMatchers()?等方法来匹配系统的?URL?,并为其指定安全策略。
(2)formLogin():对应<form-login>,formLogin.loginPage("/myLogin.html")?指定自定义的登录页为?/myLogin.html?,同时,Spring Security?会用?/myLogin.html?注册一个?POST?路由,用于接收登录请求。
(3)httpBasic()?:对应<http-basic>标签,formLogin()?和?httpBasic()?方法都声明了需要?Spring Security?提供的表单认证方式,分别返回对应的配置器。
(4)?csrf()?:对应?<csrf>标签 ,是?Spring Security?提供的跨站请求伪造防护功能,当我们继承?WebSecurityConfigurerAdapter?会默认开启?csrf()?方法
三、认证数据源UserDetailsService?:
1、介绍:Spring Security 支持各种来源的用户数据,包括内存、数据库、LDAP 等。它们被抽象为一个 UserDetailsService 接口,任何实现了 UserDetailsService 接口的对象都可以作为认证数据源。在这种设计模式下,Spring Security 显得尤为灵活。
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
2、实现类:
(1)InMemoryUserDetailsManager?:将用户数据源寄存在内存里,在一些不需要引入数据库这种重数据源的系统中很有帮助。
(2)JdbcUserDetailsManager:
(3)自定义实现类:实现UserDetailsService接口。如
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
@Service("jwtUserService")
public class JwtUserServiceImpl implements UserDetailsService {
@Autowired
private UserDOMapper userDOMapper;
@Autowired
private UserMenuMapper userMenuMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDO userDO = userDOMapper.getNonFieldAccountByAccountOrPhone(username);
if(userDO == null){
throw new UsernameNotFoundException("用户不存在");
}
// 查询用户菜单权限
List<MenuVO> menuVOList = userMenuMapper.listMenuByAccount(username,);
return new JwtUser(userDO.getId(),userDO.getAccount()
userDO.getName(), menuVOList);
}
}
其中的用户对象也重写了:
package com.security.demo.dto;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
public class JwtUser implements UserDetails {
//用户id
private String id;
//用户账号
private String account;
//用户名
private String name;
//菜单
private List<MenuVO> menuVOList;
public JwtUser(){
}
public JwtUser(String id,String account,String name,List<MenuVO> menuVOList){
this.id = id;
this.account = account;
this.name = name;
this.menuVOList = menuVOList;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return null;
}
@Override
public String getUsername() {
return name;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
?3、使用方法:只需要为自定义UserDetailsService数据源类加上@bean?注解,便可被?Spring Security?发现并使用。
四、用户对象UserDetails?:
1、介绍:
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
2、使用方法:使用时一般实现UserDetails,自定义业务字段即可。如上面的JWTUser。