Springboot整合Springsecurity
版本: springboot 2.4.0
步骤一、引入依赖
使用springsecurity必然会涉及到前端权限访问的问题,所以该用例会引入模板引擎Thymeleaf
<!-- 模板引擎Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Thymeleaf关于springsecurity的功能 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!-- security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
要在thymeleaf中使用springsecurity相关的功能(比如:springsecurity中关于用户role和权限的函数),需要引入thymeleaf-extras-springsecurity5
步骤二、springsecurity相关配置
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/","/home").permitAll() // 所有的用户都可以直接访问/home,/
.anyRequest().hasAnyRole("ADMIN")
.and()
.formLogin()
.loginPage("/login") // 自定义登陆页面
.permitAll()
.and()
// 配置logout指向的URL
.logout().logoutSuccessUrl("/logout").logoutSuccessUrl("/").permitAll();
// 启动remember功能,并且绑定到自定义登陆页面的RememberMe checkbox上
http.rememberMe().rememberMeParameter("rememberme");
}
@Bean
@Override
public UserDetailsService userDetailsService() {
// 添加两个账户到内存中,并且Role分别指定为ADMIN和USER
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("123456")
.roles("USER")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("root")
.password("root")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
关于添加账户的问题:本例是通过硬编码的形式将相关账户添加到项目内存中的,实际开发中可以将用户及其ROLE放到数据库,然后将用户数据读出并写入到UserDetailsService中。
步骤三、Controller
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class MyController {
@GetMapping("/")
public String hello(Model model) {
model.addAttribute("hello", "hello thymeleaf");
return "home";
}
@PostMapping("/login")
public String login(String username, String password, Model model) {
model.addAttribute("welcome", username);
return "home";
}
@GetMapping("/login")
public String login() {
return "login";
}
}
controller中只是简单地进行页面的跳转。
步骤四、前端页面 - Thymeleaf
home.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www/thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<meta charset="UTF-8">
<title>Home Page</title>
</head>
<body>
<!-- @{}: thymeleaf会自动加上项目的context-path -->
<div sec:authorize="isAuthenticated()">
Welcome, <span sec:authentication="name"></span>
<form action="#" th:action="@{/logout}" method="post">
<input type="submit" value ="Logout"/>
</form>
</div>
<!--Thymeleaf根据springsecurity整合的相关函数(thymeleaf-extras-springsecurity5)-->
<div sec:authorize="!isAuthenticated()">
Welcome to the Home Page! Wanna view more detail about us, pls
<a th:href="@{/login}">Login</a>
</div>
<div sec:authorize="hasRole('ADMIN')">
Your are an Administrator.
</div>
<div sec:authorize="hasRole('USER')">
Your are an Customer.
</div>
</body>
</html>
本例中根据不同的账户角色(hasRole('ADMIN'))显示不同的内容,这就是权限控制的一部分功能。根据用户是否认证(isAuthenticated())来显示用户信息或者显示登陆按钮。
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<div th:text="Login"></div>
<form th:action="@{'/login'}" method="post">
<input type="text" name="username"/>
<input type="password" name="password"/>
<!--Remember Me选择框会绑定到springsecurity的‘记住我‘功能上-->
<input type="checkbox" name="rememberme"/>Remember Me
<input type="submit" value="Login"/>
</form>
</body>
</html>
Remember Me选择框会绑定到springsecurity的‘记住我‘功能上。springsecurity配置中通过代码http.rememberMe().rememberMeParameter("rememberme");