一、依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.darren.test</groupId>
<artifactId>security-test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring.boot.version>2.2.1.RELEASE</spring.boot.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>${spring.boot.version}</version>
</dependency>
<!-- starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring.boot.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、简单使用
需要手动实现或继承以下三个类:
1. UserDetailsService
该接口返回UserDetails对象,返回用户名、密码、权限等用户基本信息,实现类主要实现相关信息的获取。
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
return new User("darren", "123", auths);
}
}
UserDetails为接口对象,需要进行实现。框架提供的实现类User基本够用。
GrantedAuthority为security提供的用于存储角色或权限信息的实体类,角色必须以“ROLE_”开头,权限不需要。
2. PasswordEncoder
密码加密接口实现,这里密码不加密。
public class NoEncryptPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence) {
return (String) charSequence;
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return s.contentEquals(charSequence);
}
}
3. WebSecurityConfigurerAdapter
该类为抽象类,提供继承以自定义安全配置。
@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailServiceImpl userDetailService;
/**
* 加密类
* @return PasswordEncoder
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new NoEncryptPasswordEncoder();
}
/**
* 配置登录实现类和密码加密类
* @param auth AuthenticationManagerBuilder
* @throws Exception 异常
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
}
/**
* 登录与权限配置
* @param http HttpSecurity
* @throws Exception 异常
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 自定义登录页面、登录接口、成功跳转,适用前后端不分离项目
http.formLogin().loginPage("/login.html").loginProcessingUrl("/auth/login").defaultSuccessUrl("/test/home").permitAll()
// 放行路径
.and().authorizeRequests().antMatchers("/test/test1", "/test/test2").permitAll()
// 登录管控路径
.and().authorizeRequests().anyRequest().authenticated()
// 关闭csrf防护
.and().csrf().disable();
}
/**
* 不定义没有password grant_type,密码模式需要AuthenticationManager支持
* @return AuthenticationManager
* @throws Exception 异常
*/
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
简单说明:
(1)formLogin().loginPage("/login.html")自定义登录页面,不定义时使用默认页面。
(2)formLogin().loginProcessingUrl("/auth/login")定义登录路径,无需编写相关控制器,由框架配置。
(3).and()用于回到HttpSecurity,继续往后配置。
(4).authorizeRequests().antMatchers("/test/test1", "/test/test2"):访问路径在括号范围内。
(5).authorizeRequests().anyRequest():所有路径
(6).permitAll()放行
(7).authenticated()需要登录
(8)权限管控另有:hasRole()、hasAnyRole()、hasAuthority()、hasAnyAuthority(),分别是有某个角色、有括号中任意一个角色、有某个权限、有括号中的任意一个权限
附:
自定义的简单页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
请登录:
<form name="f" action="/auth/login" method="post">
<br/>
用户名:
<input type="text" name="username" placeholder="name"><br/>
密码:
<input type="password" name="password" placeholder="password"><br/>
<input name="submit" type="submit" value="提交">
</form>
</body>
</html>