SpringSecurity(安全)
在web开发中 安全第一位!
什么是 SpringSecurity?
官方解释:
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements
springsecurity是一个功能强大且高度可定制的身份验证和访问控制框架。它是保护基于Spring的应用程序的事实标准。
springsecurity是一个专注于为Java应用程序提供身份验证和授权的框架。与所有Spring项目一样,Spring安全性的真正威力在于它可以很容易地扩展以满足定制需求
例如:我们做的网站 ,系统中对于不同的用户设置不同的权限 看到的页面也是不一样的 有些页面不对权限不足的用户 游客等开放 这时候我们就可以使用SpringSecurity来帮助我们完成这些事情 。
功能:认证,授权
简单的写几个页面给大家大概演示一下访问权限的问题
就是写一个首页 连接到不同的页面 不同的等级页面显示不同的内容
测试一下
首页写的很丑 大家见谅!!
点击就可以调到不同页面 所有的页面都可以访问 没有任何的阻拦 那么马上我们就要使用SpringSecurity对我们的项目实现安全管理了!
那我们怎么使用SpringSecurity?
首先我们要导入SpringSecurity的启动器!
<!--springSecurity启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
还有thymeleaf的包 因为我们页面使用了thymeleaf魔板渲染数据
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
导入进来之后 核心包多了aop,config等等
我们要使用security要配置使用规则
创建一个config 配置包 我们很多的配置都是写在config中的
创建一个配置类
security的使用步骤:
1.继承一个类extends WebSecurityConfigurerAdapter
public class SpringSecurity extends WebSecurityConfigurerAdapter {
}
2.类上加上注解@EnableWebSecurity
@EnableWebSecurity
public class SpringSecurity extends WebSecurityConfigurerAdapter {
}
3.重写一个方法configure(HttpSecurity http)
//重写授权的方法
//启用Security
@EnableWebSecurity
public class SpringSecurity extends WebSecurityConfigurerAdapter {
//方法里是链式编程
@Override
protected void configure(HttpSecurity http) throws Exception {
// super.configure(http);
//需求:首页所有人可以访问 功能页只有对应有权限的人才能访问
//定义请求授权的规则
// authorizeRequests认证请求 antMatchers添加一个地址 permitAll所有人都可以访问
http.authorizeRequests()
.antMatchers("/").permitAll()
// hasRole哪一个角色可以访问
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
}
}
重启动测试
随便点击访问level页面 发现报了403 权限不足
在方法里加上这句话 会让我们没有权限访问时候跳转到login页面 大家注意 !!!这个登录页面不是我们自己写的是spring默认提供的一个登录页面!!!
附加注销功能
//没有权限默认调到登录页面
http.formLogin();
//注销
http.logout();
那为什么会调到这样一个登录页面呢,我们点进formLogin源码看见这样一句注释
* The most basic configuration defaults to automatically generating a login page at
* the URL "/login", redirecting to "/login?error" for authentication failure. The
* details of the login page can be found on
* {@link FormLoginConfigurer#loginPage(String)}
就是说没有认证的话会转到login认证 如果认证失败会转到login?error下
接下来我们重写认证的方法 设置权限
@EnableWebSecurity
public class SpringSecurity extends WebSecurityConfigurerAdapter {
//重写授权的方法
//方法里是链式编程
@Override
protected void configure(HttpSecurity http) throws Exception {
// super.configure(http);
//需求:首页所有人可以访问 功能页只有对应有权限的人才能访问
//定义请求授权的规则
// authorizeRequests认证请求 antMatchers添加一个地址 permitAll所有人都可以访问
http.authorizeRequests()
.antMatchers("/").permitAll()
// hasRole哪一个角色可以访问
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//没有权限默认调到登录页面,需要开启登录的页面
http.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这些数据正常应该从数据库里读
//inMemoryAuthentication从内存中读
auth.inMemoryAuthentication()
.withUser("feifei").password("123456").roles("vip1","vip2")
//and拼接多个用户
.and()
.withUser("root").password("123456").roles("vip1","vip2","vip3")
.and()
.withUser("guest").password("123456").roles("vip1");
}
}
从数据库里读的官方示例
注意:
//密码编码 PassWordEncoder
//在spring Security5.0+版本中 新增了很多加密方式 如果密码没加密是不让我们使用的
认证 springboot 2.1.x的版本可以直接使用 别的版本可能不能直接使用我们是2.4
重启登录一下
spring security 官方推荐的是使用bcrypt加密方式。
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这些数据正常应该从数据库里读
//inMemoryAuthentication从内存中读 passwordEncoder:设置密码加密的方式 new一个加密方式
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
//withUser哪个用户password密码roles角色 new BCryptPasswordEncoder().encode("123456")加密密码
.withUser("feifei").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
//and拼接多个用户
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
加入密码加密之后 我们就可以登录了
重启测试
登录成功 我们的权限是一二 访问不了三测试一下
访问三权限不够
测试一下之前加入的登出方法 有没有效果
登出的方法页面加入这句
<!-- 如果已登录 显示用户名、注销 -->
<!-- Security 的退出链接: /logout (必须这么写)-->
<div sec:authorize="isAuthenticated()">
用户名:<span sec:authentication="name"></span>
<a th:href="@{/logout}">
注销</a>
</div>
点击注销 就会跳到