一,认识spring-security
从本质上讲,Spring Security 实际上只是一堆 servlet 过滤器,可帮助您向Web应用程序添加身份验证和授权。还与 Spring Web MVC(或 Spring Boot)之类的框架以及 OAuth2 或SAML 之类的标准很好地集成。并且它会自动生成登录/注销页面,并防御 CSRF 等常见漏洞。
1 ,授权:就是你的用户有哪些权限
2,身份验证:就是你属不属于这个用户
二,环境搭建 和 授权认证 以及 权限控制
(1)环境搭配
① . 第一步:创建一个springboot的项目
② .第二步:导入security环境
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
③ .第三步:创建配置类并继承 “WebSecurityConfigurerAdapter”
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
#特别注意:想要这个类里的东西生效就要标注@EnableWebSecurity(开启websecurity模式)
(2)授权认证
<1> 重写WebSecurityConfigurerAdapter类里的方法
①.重写configuer(HttppSecurity http)方法 【作用:注释上标有 方法解释在下面】
/**
* 授权
* antMatchers("/").permitAll()[可以写多组,结尾用;就好]
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("level1/**").hasRole("vip1");
http.formLogin();
}
②.重写configure(AuthenticationManagerBuilder auth)方法 【作用:注释上标有 】
/**
* 认证
* withUser( ).password( ).roles( );【可写多组】
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().withUser("dong").password("123").roles("vip1","vip2");
}
HttpSecurity 授权:
authorizeRequests: 授权请求
antMatchers():姑且叫他匹配器吧
permitAll()允许全部
hasAnvRole()任何角色都可以访问
hasRole() 限定角色
fromLogin() 就是没有权限就跳到登录页面
认证:
inMemoryAuthentication(从内存中认证)
jdbcAuthentication(认证jdbc里的)/本文没有使用/
with User :用户
password: 密码
roles :设置角色
#授权认证遇到的问题
错误1.
Error creating bean with name 'springSecurityFilterChain' defined in class path resource
NoClassDefFoundError: org/springframework/jdbc/core/support/JdbcDaoSupport
解决思路:先看一下自己的路径有没有错,然后顺着报错信息发现我用的是jdbc的认证方式
错误2.
There is no PasswordEncoder mapped for the id "null"
在2.1.x版本或一下就不会报错,
密码编码:PasswordEncoder
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(new BCryptPasswordEncoder())
.withUser("dong").password(new BCryptPasswordEncoder().encode("123")).roles("vip1","vip2")
.and()
.withUser("root").password("123").roles("vip1","vip2","vip3");
}
加了一个.passwordEncoder(new BCryptPasswordEncoder()) ,然后再配置了编码方式.encode,下面一个没改可以对比【设置加密方式】这个其实有很多,直接到源码中就可以查找
或许也可以用解决There is no PasswordEncoder mapped for id “null” - 知乎 (zhihu.com)这里的解决方案
(3)权限控制
准备工作 ------------------------------- 我们要用到的环境----------------------------------------
<!--thymeleaf和安全的整合包-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
我自己的springboot的版本 2.6.6版
引入名空间xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5" 把后面改成4就会有提示,但是会报错,用来偷懒也是很不错的
下面就直接代码演示了
<--
sec: 就相当于thymeleaf 里的 th 一样的意思
authorize:见名知意了,就是授权,你要授权啥么东西
isAuthenticated() :身份验证 主要功能:指示当前用户是否已通过身份验证,如果没有通过就显示登录‘按钮’
下面的就是一些正常的前端代码了,就不做解释了
-->
<div sec:authorize="!isAuthenticated()">
<!--未登录-->
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i> 登录
</a>
</div>
<--hasRole : 就是你后端设置的角色-->
<div class="column" sec:authorize="hasRole('vip1')">
替换login页面。源码中写到
loginPage("/authentication/login") // default is /login with an HTTP get
所以设置login自己的方法就是loginPage,要注意的是你的login。html中也要改成你设置的路径,不然会找不到