思路分析
在这块我们利用springboot整合security简单做个小小的权限分配作业,由于目的仅仅是当做在学习security过程的知识练习巩固,因此代码思路比较简单,前端部分由几个简单的html页面充当。大概需求目的是这样:我在后端注册了三个用户,分别为admin,user,person,他们的密码均是123456,然后我又创建了两个角色,分别是管理员角色admin与员工角色user,然后对于资源的分配即对接口的权限分配如下,对于员工角色只有访问员工页面接口的权限,而对于管理员角色则具又既能访问员工页面接口的权限同时又能访问管理员页面接口的权限。然后我便将管理员角色分配给admin,将员工角色分配给user,其中对于游客页面是共享资源即所有人均能访问,因此对于person即游客用户不分配任何用户。用户-角色-权限 三者关系如下、
好了大概思路有了,那么下面开始写代码~~
搭建项目
首先利用框架快速创建一个springboot项目
所需要导的依赖如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
资源接口实现
然后构建好项目目录后先写接口资源(在这指利用springmvc进行跳转的接口)
package com.boot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class IndexController {
/*
* @description: 登录成功跳转的首页
**/
@GetMapping("/index")
public String index() {
return "index";
}
/*
* @description: 管理员接口,仅仅管理可用
**/
@GetMapping("/admin/api")
public String admin() {
return "admin";
}
/*
* @description: 员工接口,员工与管理员均可用
**/
@GetMapping("/user/api")
public String user() {
return "user";
}
/*
* @description: 游客接口,所有人都可访问
**/
@GetMapping("/person/api")
public String person() {
return "person";
}
/*
* @description: 没有权限的访问接口
**/
@GetMapping("/auth")
public String auth() {
return "auth";
}
}
还有登录接口
package com.boot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class LoginController {
/*
* @description: 登录接口
**/
@GetMapping("/login")
public String login() {
return "login";
}
}
页面资源实现
写完controller接口之后再把页面资源给写了,都是些简单html的内容
登录页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>主页面</title>
</head>
<body>
<h1 style="background-color: red">登录页面</h1>
<form th:action="@{/login}" method="post">
账号: <input type="text" name="username" placeholder="请输入账号:"> <br>
密码: <input type="text" name="password" placeholder="请输入密码:"> <br>
<input type="submit" value="登录">
</form>
<form th:action="@{/logout}" method="post">
<input type="submit" value="退出">
</form>
</body>
</html>
主页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>主页面</title>
</head>
<body>
<h1>欢迎来到主页面!!!</h1>
<a th:href="@{/admin/api}">管理员页面</a>
<a th:href="@{/user/api}">员工页面</a>
<a th:href="@{/person/api}">游客页面</a>
</body>
</html>
管理员页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>管理员页面</title>
</head>
<body>
<h1 style="background-color: darkgoldenrod">管理员页面</h1>
</body>
</html>
员工页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>员工页面</title>
</head>
<body>
<h1 style="background-color: blueviolet">员工页面</h1>
</body>
</html>
游客页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>游客页面</title>
</head>
<body>
<h1 style="background-color: darkred">游客页面</h1>
</body>
</html>
未授权页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>未授权页面</title>
</head>
<body>
<h1 style="background-color: darkred">未授权页面</h1>
</body>
</html>
配置信息书写
写完这些资源文件之后剩下的就是整个项目的核心所在即配置文件的书写
package com.boot.config;
import com.boot.handler.LoginFailureHandler;
import com.boot.handler.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private LoginSuccessHandler loginSuccessHandler;
@Autowired
private LoginFailureHandler loginFailureHandler;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 先写权限配置
http.authorizeHttpRequests(authorizeHttpRequests ->
authorizeHttpRequests
//对接口资源配置相应权限以及分配角色
//管理页面分配给管理员角色
.requestMatchers("/admin/api").hasRole("admin")
//员工页面分配给管理员角色与员工角色
.requestMatchers("/user/api").hasAnyRole("admin", "user")
//游客页面所有人均有权限即所有人都能访问
.requestMatchers("/person/api").permitAll()
//所有人都能登录
.requestMatchers("/login").permitAll()
.anyRequest().authenticated() // 任何请求访问的时候都需要进行认证
);
//配置登录页面
http.formLogin(fromLogin ->
fromLogin.
//登录接口
loginPage("/login")
//登录页面数据提交路径
.loginProcessingUrl("/login").permitAll()
//登录成功后跳转的页面
.defaultSuccessUrl("/index")
//登录成功处理器
// .successHandler(loginSuccessHandler)
//登录失败处理器
// .failureHandler(loginFailureHandler)
);
//模拟配置未授权访问页面(用异常处理器来实现)
http.exceptionHandling(e->e.accessDeniedPage("/auth"));
//跨域漏洞防御关闭
http.csrf(Customizer.withDefaults());
//退出配置
http.logout(logout -> logout.invalidateHttpSession(true));
return http.build();
}
//配置用户以及给用户分配角色
@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
//给admin用户分配管理员角色
UserDetails user1 = User.withUsername("admin")
.password("123456")
.roles("admin").build();
//给user用户分配员工角色
UserDetails user2 = User.withUsername("user")
.password("123456")
.roles("user").build();
//普通用户person不分配角色
UserDetails user3 = User.withUsername("person")
.password("123456").build();
//对三用户进行注册返回
return new InMemoryUserDetailsManager(user1,user2,user3);
}
//给密码明文加密
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
对于上面每个配置都有写了含义注解,其中因为登录成功跳转的配置与登录成功处理器发生冲突,因此对于上面虽然写了其配置但是没用上,然后代码写完了之后启动项目
启动项目
启动了项目之后,我们随便访问一个地址,然后由于security认证的拦截,并且我在登录配置中配置了自定义登录页面,因此会跳转到登录页面进行登录
项目效果演示
登录成功后来到系统主页
首先演示admin用户权限(理论上对于所有页面均可访问)
然后是user用户(理论上只能访问员工页面与游客页面,对于管理员页面因为没有权限访问会跳转到未授权页面)
最后是person用户(理论上只能访问游客页面)
到此项目演示结束,由于是第一次写博客,文字排版比较差,思路逻辑也没表达清楚,所以希望大家能够体谅,并且对于大家给的建议我也会积极吸取改进,对于内容中如果有知识性的错误的话也乐意接受大家的指出,最后希望大家能够从中获取到自己想要的帮助!!!谢谢支持