前言:
在web开发中,安全第一位!
功能性需求:否
做网站:安全应该在什么时候考虑?设计之初!
- 漏洞,隐私泄漏~
- 架构一旦确定~
shiro,SpringSecurity:很像~除了类不一样,名字不一样;
认证,授权(vip1,vip2,vip3)
- 功能权限
- 访问权限
- 菜单权限
- …拦截器,过滤器:大量原生代码~冗余
SpringSecurity简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。
Spring Security对Web安全性的支持大量地依赖于Servlet过滤器。这些过滤器拦截进入请求,并且在应用程序处理该请求之前进行某些安全处理。 Spring Security提供有若干个过滤器,它们能够拦截Servlet请求,并将这些请求转给认证和访问决策管理器处理,从而增强安全性。根据自己的需要,可以使用适当的过滤器来保护自己的应用程序。
资料来自百度百科~ SpringSecurity
记住几个类:
- WebSecurityConfigurationAdapter:自定义Security策略。
- AuthenticationManagerBuilder:自定义认证策略
- @EnableWebSecurity:开启WbSercurity模式,@Enablexxx开启某个功能
Spring Security两个重要目标"认证" “授权”(访问控制)
“认证”(Authentication)
“授权”(Authorization)
SpringSecurity环境配置
首页,第一步还是导入依赖。这里同时整合了thymeleaf。
<!--Spring security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--thymeleaf依赖-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!--SpringBoot中使用thymeleaf功能可以直接用下面这个依赖-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
<!-- </dependency>-->
<!--thymeleaf整合springsecurity-->
SpringSecurity 用户认证与授权
首先来看一下我们项目的初始分布
如上图所示,我们将在views目录下,给视图分了等级level1、level2、level3。并提供了给前端的请求路径。在没有任何权限管理的情况下,只要服务器开启,那么前端用户登录均可以访问这些页面。以下使用Security进行授权与认证的案例。SecurityConfig为自定义类。
package com.kuang.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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//首页所有人可以访问,功能页只有对应有权限的人才能访问
@Override
protected void configure(HttpSecurity http) throws Exception {
//请求授权的规则
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//设置没有权限回到login页面
http.formLogin();
//自定义登录页面
// http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login").usernameParameter("user").passwordParameter("pwd");
//开启注销功能,链接为 /logout
// http.logout().deleteCookies("remove").invalidateHttpSession(false);
http.logout().logoutUrl("/custom-logout").logoutSuccessUrl("/");//注销后的地址
//添加记住我功能,保存包含登录信息的cookie。默认为两周。
http.rememberMe().rememberMeParameter("remember");
}
//认证,springboot 2.1.x可以直接使用
//密码编码:PasswordEncoder
//在Spring Security 5.0+ 新增了很多的加密方法~
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
.and()
.withUser("tomcat").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2");
}
}
登录页面定制
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>定制登录页面</h1>
<form th:action="@{/login}" method="post">
<input type="text" name="user">
<input type="password" name="pwd">
<input type="submit" value="登录">
记住我<input type="checkbox" name="remember">
</form>
</body>
</html>
首页定制
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" th:href="@{/css/index.css}"/>
</head>
<body>
<div class="nav-bar">
<!--授权后不需要在登录-->
<a th:href="@{/toLogin}" sec:authorize="!isAuthenticated()">登录</a>
<!-- <a th:href="@{/logout}">注销</a>-->
<form th:action="@{/custom-logout}" method="post">
<input type="submit" value="注销">
</form>
<span sec:authorize="isAuthenticated()">
用户名:<i sec:authentication="name"></i>
角色:<i sec:authentication="principal.authorities"></i>
</span>
</div>
<div class="container">
<div class="piece" sec:authorize="hasRole('vip1')">
<p class="piece-title">等级:Level1</p>
<div class="nav-link">
<a th:href="@{/level1/1}">页面1</a>
<a th:href="@{/level1/2}">页面2</a>
<a th:href="@{/level1/3}">页面3</a>
</div>
</div>
<div class="piece" sec:authorize="hasRole('vip2')">
<p class="piece-title">等级:Level2</p>
<div class="nav-link">
<a th:href="@{/level2/1}">页面1</a>
<a th:href="@{/level2/2}">页面2</a>
<a th:href="@{/level2/3}">页面3</a>
</div>
</div>
<div class="piece" sec:authorize="hasRole('vip3')">
<p class="piece-title">等级:Level3</p>
<div class="nav-link">
<a th:href="@{/level3/1}">页面1</a>
<a th:href="@{/level3/2}">页面2</a>
<a th:href="@{/level3/3}">页面3</a>
</div>
</div>
</div>
</body>
</html>
使用thymeleaf之前可以现在application.yaml配置文件中关闭thymeleaf的缓存。
spring:
thymeleaf:
cache: false