介绍

在web开发中,安全是特别重要的!一般我们实现安全的手段有过滤器、拦截器…

我们使用SpringSecurity、shiro两个框架是为了更加简洁的实现安全。

Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。 它是保护基于 Spring 的应用程序的事实标准。

Spring Security 是一个专注于为 Java 应用程序提供身份验证和授权的框架。 与所有 Spring 项目一样,Spring Security 的真正强大之处在于它可以轻松扩展以满足自定义需求

注意点

image-20230206201554494

相关依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
//SpringSecurity配置依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!--对Thymeleaf添加Spring Security标签支持-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!--通过整合依赖,我们可以实现对前端页面也进行安全验证-->

配置实现

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
package com.demo.config;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

//开启注解配置
//@EnableWebSecurity是Spring Security用于启用Web安全的注解。
// 典型的用法是该注解用在某个Web安全配置类上(实现了接口WebSecurityConfigurer或者继承自WebSecurityConfigurerAdapter)。
@EnableWebSecurity
public class securityConfig extends WebSecurityConfigurerAdapter {
//其中通过继承WebSecurityConfigurerAdapter从而实现相关的方法来实现需要的功能


//授权
@Override
protected void configure(HttpSecurity http) throws Exception {

}

//认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 目前可以直接使用
//需要对密码进行安全加密,在springSecurity5中新增了很多加密格式
//加密方式: passwordEncoder(new BCryptPasswordEncoder())

}

}

image

最主要的两个方法

认证

通过实现对相关用户的权限赋值,从而实现不同权限展现出来的东西也不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 //认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 目前可以直接使用
//需要对密码进行安全加密,防止反编译破解密码在springSecurity5中新增了很多加密格式
//加密方式: passwordEncoder(new BCryptPasswordEncoder())


//设置相关用户对应的权限roles
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("root").password(new BCryptPasswordEncoder().encode("520010")).roles("vip1","vip2")
.and()
.withUser("tempUser").password(new BCryptPasswordEncoder().encode("520010")).roles("vip1")
.and()
.withUser("rayce").password(new BCryptPasswordEncoder().encode("520010")).roles("vip1","vip2","vip3");

}
}

授权

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
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//设置页面的访问权限,例如 /所有人都可以访问
//其他的功能页,只有对应相关功能权限的人才能进行访问 。 比如:”/first1/**“路径下的所有页面只有有vip1权限的用户可以访问
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/first1/**").hasRole("vip1")
.antMatchers("/first2/**").hasRole("vip2")
.antMatchers("/first3/**").hasRole("vip3");

//定制登录页面
//loginPage 需要跳转的登录页面。默认为login
//usernameParameter : 在执行身份验证时查找用户名的 HTTP 参数。默认值为“username” 也可以自定义修改,但是必须和对应属性的name相同用户名参数 – 在执行身份验证时查找用户名的 HTTP 参数
//password和username处理方法相同
//successUrl 转发身份验证成功处理程序
//loginProcessingUrl 指定用于验证凭据的 URL。
http.formLogin().loginPage("/to/login").usernameParameter("username").passwordParameter("password").loginProcessingUrl("/login");

//防止用户信息被获取
http.csrf().disable();
//作用是记住我, 也就是保存cookie,当我们退出网站时,当时登录的用户不会退出,一般默认保存的cookie为两周
//rememberMeParameter中的内容时点击记住我按钮的name属性
http.rememberMe().rememberMeParameter("remember");

//注销 。以及注销成功时需要跳转的请求的地址
http.logout().logoutSuccessUrl("/index");
}

前端页面使用security

注意修改pom中的parent版本为3.0.4.RELESE,这样才会显示我们需要展示的效果,但是页面效果会大打折扣

添加命名空间

命名空间改为xmlns:sec=”http://www.thymeleaf.org/extras/spring-security5

image

使用:

image

对于不同板块不同权限的人可见的设置

1
2
3
4
5
6
7
8
9
<div class="XXX1" sec:authorize="hasRoles('vip1')">
//需要展示的内容
</div>
<div class="XXX2" sec:authorize="hasRoles('vip2')">
//需要展示的内容
</div>
<div class="XXX3" sec:authorize="hasRoles('vip3')">
//需要展示的内容
</div>