# Spring Security的使用
# 概述
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
- 它是一个轻量级的安全框架,它确保基于Spring的应用程序提供身份验证和授权支持。
- 它与Spring MVC有很好地集成,并配备了流行的安全算法实现捆绑在一起。安全主要包括两个操作“认证”与“验证”(有时候也会叫做权限控制)。
- “认证”是为用户建立一个其声明的角色的过程,这个角色可以一个用户、一个设备或者一个系统。“验证”指的是一个用户在你的应用中能够执行某个操作。在到达授权判断之前,角色已经在身份认证过程中建立了。
- Spring Security 前身是Acegi Security
# 官网
https://spring.io/projects/spring-security
# HelloWorld
# 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 启动项目
访问系统使用用户名默认 user
启动成功后会生成一个默认密码,控制台输出
Using generated security password: 6e86c6e9-d661-41ae-aabc-bea8817c4f7b
1
UserDetailsServiceAutoConfiguration类
# 自定义用户名密码
# 配置文件
spring.security.user.name=111
spring.security.user.password=111
1
2
2
# 类定义
@Configuration
@EnableWebSecurity
public class MyConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// TODO Auto-generated method stub
auth.inMemoryAuthentication()
.withUser("111")
.password("222")
.roles("admin");
// super.configure(auth);
}
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 基于内存存储的多用户
auth.inMemoryAuthentication()
.withUser("111")
.password("222")
.roles("admin")
.and()
.withUser("333")
.password("444")
.roles("xxoo");
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
或者
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
User user = new User("a", new BCryptPasswordEncoder().encode("1"), true, true, true, true, Collections.singletonList(new SimpleGrantedAuthority("xx")));
manager.createUser(user);
manager.createUser(User.withUsername("yiming").password(new BCryptPasswordEncoder().encode("xx")).roles("xxz").build());
return manager;
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Security中的User对象
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;
1
2
3
4
5
6
7
2
3
4
5
6
7
# Session中存储的对象
Enumeration<String> attributeNames = request.getSession().getAttributeNames();
// while (attributeNames.hasMoreElements()) {
// String string = (String) attributeNames.nextElement();
// System.out.println(string);
// System.out.println(request.getSession().getAttribute(string));
//
// }
SecurityContext attribute = (SecurityContext)request.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
System.out.println(attribute.getAuthentication().getAuthorities());
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 忽略静态请求
@Override
public void configure(WebSecurity web) throws Exception {
// TODO Auto-generated method stub
web.ignoring().antMatchers("/img/**","/js/**");
// super.configure(web);
}
1
2
3
4
5
6
2
3
4
5
6
# 自定义登录页面
@Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
http.authorizeRequests()
//所有请求都需要验证
.anyRequest().authenticated()
.and()
//permitAll 给没登录的 用户可以访问这个地址的权限
.formLogin().loginPage("/login.html").permitAll();
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 自定义表单属性
配置类中
@Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
http.authorizeRequests()
//所有请求都需要验证
.anyRequest().authenticated()
.and()
//permitAll 给没登录的 用户可以访问这个地址的权限
.formLogin().loginPage("/login.html")
//自定义表单
.usernameParameter("xx")
.passwordParameter("oo")
.loginProcessingUrl("/login")
.failureUrl("/login.html?error")
.defaultSuccessUrl("/").permitAll()
.and()
.csrf().csrfTokenRepository(new HttpSessionCsrfTokenRepository())
;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21