Spring Security(安全)
简介
spring security 的核心功能主要包括:
认证 (你是谁) 授权 (你能干什么) 攻击防护 (防止伪造身份) 其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。
Spring Security是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入spring-boot-starter-security模块,进行少量的配置,即可实现强大的安全管理!
有几个类:
. WebSecurityConfigurerAdapter:自定义Security策略
. AuthenticationManagerBuilder:自定义认证策略
. @EnableWebSecurity:开启WebSecurity模式
Spring Security的两个主要目标是
“认证”和“授权”(访问控制)。
“认证”(Authentication)
“授权”(Authorization)
这个概念是通用的,而不是只在Spring Security中存在。
参考官网: https://spring.io/projects/spring-security,查看我们自己项目中的版本,
找到对应的帮助档:https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/#using-boot-starter
HttpSecurity 常用方法及说明:
导入起动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--thymeleaf security整合包-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
使用sec,Spring Boot的版本必须降到:2.0.9.RELEASE
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.9.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
使用sec:需要在HTML头部导入:
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"
Controller包下的RouterController
package com.yuan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RouterController {
/**
* 跳转主页面
* @return
*/
@RequestMapping({"/","/index"})
public String index(){
return "index";
}
/**
* 跳转登录页面
* @return
*/
@RequestMapping("/toLogin")
public String toLogin() {
return "login";
}
/**
* 主页面跳转
* @param name
* @return
*/
@RequestMapping("/Node/{name}")
public String toNode(@PathVariable("name") String name) {
System.out.println(name);
return "/Node/"+name;
}
/**
* 页面跳转
* @param name
* @return
*/
@RequestMapping("/Role/{name}")
public String toRole(@PathVariable("name") String name){
return "/Role/"+name;
}
/**
* 页面跳转
* @param name
* @return
*/
@RequestMapping("/User/{name}")
public String toUser(@PathVariable("name") String name){
return "/User/"+name;
}
}
config包下的SecurityConfig
package com.yuan.config;
import org.springframework.context.annotation.Configuration;
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;
/**
* Spring Security
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问permitAll,功能只有对应的权限的人才能访问hasRole
//权限规则
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/Node/**").hasRole("vip1")
.antMatchers("/Role/**").hasRole("vip2")
.antMatchers("/User/**").hasRole("vip3");
//没有权限跳转到登录页面 loginPage自定义页面
http.formLogin().loginPage("/toLogin");
//防止网站攻击:get post
http.csrf().disable();//关闭//csrf功能 登出失败的可能的原因
//注销跳转到首页 logoutSuccessUrl跳转页面
http.logout().logoutSuccessUrl("/");
//开启记住我功能 默认保存的是两周
http.rememberMe();
}
//认证
//BCryptPasswordEncoder密码加密算法
// .withUser("用户名").password(new BCryptPasswordEncoder().encode("密码")).roles("权限访问的页面")
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and().withUser("hhh").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
.and().withUser("aaa").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
}
login.html
<form class="form-signin" method="post" th:action="@{/toLogin}">
<h2 class="form-signin-heading">登录系统</h2>
<input type="text" name="username" class="input-block-level" placeholder="账号">
<input type="password" name="password" class="input-block-level" placeholder="密码">
<p><button class="btn btn-large btn-primary" type="submit">登录</button></p>
</form>
index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<style>
.div1{
display: inline-block;
margin-left: 20px;
}
</style>
</head>
<body>
<!--如果未登录-->
<!--isAuthenticated()判断当前的用户是被认证-->
<div sec:authorize="!isAuthenticated()">
<a th:href="@{/toLogin}">登录</a>
</div>
<!--如果登录:显示用户名:注销-->
<div sec:authorize="isAuthenticated()">
<p>用户名:<span sec:authentication="name"></span></p>
<p><a th:href="@{/logout}">注销</a></p>
</div>
<!--有vip1显示-->
<div class="div1" sec:authorize="hasRole('vip1')">
<h1>Node</h1>
<p><a href="/Node/add">add.html</a></p>
<p><a href="/Node/edit">edit.html</a></p>
<p><a href="/Node/index">index.html</a></p>
</div>
<!--通过用户的角色动态实现-->
<!--有vip2显示-->
<div class="div1" sec:authorize="hasRole('vip2')">
<h1>Role</h1>
<p><a href="/Role/add">add.html</a></p>
<p><a href="/Role/edit">edit.html</a></p>
<p><a href="/Role/index">index.html</a></p>
</div>
<!--有vip3显示-->
<div class="div1" sec:authorize="hasRole('vip3')">
<h1>User</h1>
<p><a href="/User/add">add.html</a></p>
<p><a href="/User/edit">edit.html</a></p>
<p><a href="/User/index">index.html</a></p>
</div>
</body>
</html>