Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。
一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多,因为相比与SpringSecurity,Shiro的上手更加的简单。
一般Web应用的需要进行认证和授权。
认证:验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户
授权:经过认证后判断当前用户是否有权限进行某个操作
而认证和授权也是SpringSecurity作为安全框架的核心功能。
1、新建一个SpringBoot项目,pom里添加springsecurity的依赖和Thymeleaf依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2、创建Spring Security的配置类
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;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
// 访问"/admin"路径的 需要有ADMIN身份
.antMatchers("/admin").hasRole("ADMIN")
// 访问"/"和"/home"路径的 需要有USE身份
.antMatchers("/", "/home").hasRole("USER")
// 而其他的请求都需要认证
.anyRequest()
.authenticated()
.and()
// 修改Spring Security默认的登陆界面
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
//基于内存来存储用户信息
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("user").password(new BCryptPasswordEncoder().encode("123")).roles("USER").and()
.withUser("admin").password(new BCryptPasswordEncoder().encode("456")).roles("USER","ADMIN");
}
}
3、Controller层代码与前端代码
SecurityController.java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class SecurityController {
public static final String PAGE_HOME = "home";
public static final String PAGE_LOGIN = "login";
public static final String PAGE_ADMIN = "admin";
public static final String PAGE_USER = "user";
public static final String PAGE_GUEST = "guest";
public static final String PAGE_HELLO = "hello";
@GetMapping(value = {"/home","/"})
public String home(){
return PAGE_HOME;
}
@GetMapping(value = "/hello")
public String hello(){
return PAGE_HELLO;
}
@GetMapping(value = "/login")
public String login(){
return PAGE_LOGIN;
}
@GetMapping(value = "/admin")
public String admin(){
return PAGE_ADMIN;
}
}
hello.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Hello World!</title>
</head>
<body>
<h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
<form th:action="@{/logout}" method="post">
<input type="submit" value="Sign Out"/>
</form>
</body>
</html>
login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example </title>
</head>
<body>
<div th:if="${param.error}">
Invalid username and password.
</div>
<div th:if="${param.logout}">
You have been logged out.
</div>
<form th:action="@{/login}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>
admin.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1 class="my-5">Welcome to the Admin Dashboard</h1>
<!-- Display the username of the logged-in user -->
<div>
<p>Hello">User</strong>!</p>
</div>
<!-- Admin features -->
<h3 class="my-3">Admin Features</h3>
<ul>
<li><a href="/admin/users">Manage Users</a></li>
<li><a href="/admin/reports">View Reports</a></li>
<li><a href="/admin/settings">System Settings</a></li>
</ul>
<a href="/logout" class="btn btn-danger mt-3">Logout</a>
</div>
<!-- Optional Bootstrap JS for interactive features -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
</body>
</html>
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
</head>
<body>
<h1>Welcome to the Home Page</h1>
<p><a href="/login">Login</a></p>
</body>
</html><!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example</title>
</head>
<body>
<h1>Welcome!</h1>
<p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
</body>
</html>
4、运行结果与分析
当我们直接访问localhost:8081/hello时,此时页面将跳转到http://localhost:8081/login,这是因为SecurityConfig类配置了仅对 “/” 和 "/home"路径的请求有USER身份即可访问,"/admin"请求需要有"ADMIN"身份才可以访问。(注:这里端口我因为做了调整,改为了8081,大家照常访问8080端口即可。)
ADMIN权限的账号登录认证的时候
当访问http://localhost:8081/admin的时候会重定向到http://localhost:8081/login来鉴权认证,输入
- admin
- 456
则可以访问到 http://localhost:8081/admin 页面
USER权限的账号登录认证的时候
当访问http://localhost:8081/home的时候会重定向到http://localhost:8081/login来鉴权认证,输入
- user
- 123
则可以访问到 http://localhost:8081/home页面
而这个账号有权限的地方主要是这里配置的,给了admin账号赋予了USER、ADMIN权限
参考Spring Security最简单全面教程(带Demo)_spring security demo-CSDN博客