SpringSecurity
gitee地址: https://gitee.com/infiniteStars/spring-security
笔记根据B站狂神说整理得到的,建议结合视频阅读笔记。
学习地址: https://docs.spring.io/spring-security/site/docs/5.2.0.RELEASE/reference/htmlsingle/
前言:
- 在做网站开发时,安全是第一位。
- 以前学过的 过滤器,拦截器也可以实现,但使用框架更简便。
- 应该在做网站之初就考虑安全,因为架构一旦确定,想修改就比较麻烦。
1.首先看一下项目结构,我们要实现以下几个功能。
- 用户只能进入自己有权限的页面。例如VIP1用户只能进入level1页面。
- 用户只能看到自己权限的界面。
- 用户登陆成功后,显示注销功能,用户名和权限。
- 用户未登录时,只显示登录功能。
- 实现记住我 功能,用户下次登录时直接进入主页。
2.编写Controller层
- 主要是为了实现视图跳转
@Controller
public class RouterController {
@RequestMapping({"/","/index"}) //可以填写多个路径
public String index(){
return "index";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "views/login";
}
@RequestMapping("/level1/{id}")
public String level1(@PathVariable("id") int id){
return "views/level1/"+id;
}
@RequestMapping("/level2/{id}")
public String leve2(@PathVariable("id") int id){
return "views/level2/"+id;
}
@RequestMapping("/level3/{id}")
public String level3(@PathVariable("id") int id){
return "views/level3/"+id;
}
}
3.在Config中实现安全
- 下边的写法都是固定的套路,只需记住即可。
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().
antMatchers("/").permitAll() //任何人都可以访问首页
.antMatchers("/level1/**").hasRole("vip1") //vip1等级的可以访问level1
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//没有权限,默认回到登录页面
http.formLogin();
//注销成功后 返回首页 而不是登录页面
// http.logout();
http.logout().logoutSuccessUrl("/");
// 实现记住我功能
// http.rememberMe();
// 实现自定义的记住我功能
http.rememberMe().rememberMeParameter("remember");
}
//认证
@Override //passwordEncoder(new BCryptPasswordEncoder()) 对密码进行加密,否则会报错
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//下边的数据应该从数据库中获取
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("dz").password(new
BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("zsq").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
}
4.在前端实现显示相应页面的功能
- 注意:这里要导入springsecurity5版本的整合包,因为在SpringBoot中thymeleaf的版本默认为5,我们要导入与之相对应的。
<!--thymeleaf——security 整合包 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
- 修改前端代码时,要导入下方的命名空间。写错了没有自动提示。
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
- 用户未登录时,只显示登录功能。由 sec:authorize="!isAuthenticated()" 实现。
<div sec:authorize="!isAuthenticated()">
<!--未登录-->
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i> 登录
</a>
</div>
- 用户登陆成功后,显示注销功能,用户名和权限。
<div sec:authorize="isAuthenticated()">
<a class="item">
用户名:<span sec:authentication="name"></span>
权限:<span sec:authentication="principal.authorities"></span>
</a>
<!--注销-->
<a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i> 注销
</a>
</div>
- 相应的权限展示相应的页面 由**sec:authorize=“hasRole(‘vip1’)” **实现。
<div class="column" sec:authorize="hasRole('vip1')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 1</h5>
<hr>
<div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
<div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
<div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
</div>
</div>
</div>
</div>