0%

springSecurity简介

springSecurity简介

Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案,其本质是一个过滤器链

名词解释

**主体(principal)**使用系统的用户或设备或从其他系统远程登录的用户等等,谁在使用该系统

**认证(authentication)**权限管理系统确认一个主体的身份,允许主体进入系统,“主体”证明自己是谁。

**授权(authorization)**将操作系统的“权力”授予“主体”,这样主体就具备了操作系统中特定功能的能力,授权就是给用户分配权限

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

进行认证

UsernamePasswordAuthenticationFilter

对/login 的 POST 请求做拦截,校验表单中用户名,密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}

String username = obtainUsername(request);
String password = obtainPassword(request);

if (username == null) {
username = "";
}

if (password == null) {
password = "";
}

username = username.trim();

UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);

// Allow subclasses to set the "details" property
setDetails(request, authRequest);

return this.getAuthenticationManager().authenticate(authRequest);
}
1
2
3
4
5
# 配置用户名,密码
security:
user:
name: admin
password: admin

其中的用户名密码都是spring security生成或者配置的,但是在实际使用中用户名和密码都是从数据库去进行读取的,所以这段逻辑需要进行自定义,如果需要自定义逻辑时,需要实现 UserDetailsService 接口

1
2
3
4
public interface UserDetailsService {

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/login.html") // 自定义编写登录页面
.loginProcessingUrl("/user/login") // 登录访问路径
.defaultSuccessUrl("/index").permitAll() // 登陆成功之后跳转路径

.and().logout().logoutUrl("/logout") // 退出登录的路径
.logoutSuccessUrl("/index").permitAll() // 退出登录成功的页面

.and().authorizeRequests() // 设置认证情况
.antMatchers("/","/test/","/user").permitAll() // 可以直接访问,不需要认证
.antMatchers("/admin/").hasAuthority("admin") // 需要admin权限
.antMatchers("/teacher/").hasAnyAuthority("admin","teacher") // 如果可以有多个权限可以访问,使用hasAnyAuthority
.antMatchers("/super/").hasRole("admin") // 会拼接一个ROLE_前缀,使用的是角色是 ROLE_admin
.antMatchers("/student/").hasAnyRole("admin","teacher","student") // 多个角色
.anyRequest().authenticated() // 其他需要认证
.and().csrf().disable() // 关闭csrf防护
.exceptionHandling().accessDeniedPage("/unauth.html"); // 配置没有权限访问的自定义页面
}
}