会话管理之Spring Security的使用

3/18/2021 Spring Security

# 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

# 启动项目

image-20200508165901345

  • 访问系统使用用户名默认 user

  • 启动成功后会生成一个默认密码,控制台输出

    Using generated security password: 6e86c6e9-d661-41ae-aabc-bea8817c4f7b
    
    1

UserDetailsServiceAutoConfiguration类

# 自定义用户名密码

# 配置文件

spring.security.user.name=111
spring.security.user.password=111
1
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

# 基于内存存储的多用户

		auth.inMemoryAuthentication()
			.withUser("111")
			.password("222")
			.roles("admin")
			.and()
			.withUser("333")
			.password("444")
			.roles("xxoo");
1
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

# 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

# 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

# 忽略静态请求

@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

# 自定义登录页面

	@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

# 自定义表单属性

配置类中

	@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