SpringSecurity是一个安全框架,使用它可让咱们的系统变得安全一点,它能够对登录系统的用户进行验证和受权
一个安全的系统须要作的事情不少,好比:防SQL注入、XSS攻击、CSRF等等,
还须要对每个登录系统的用户进行权限认证,即决定了每一个用户能作什么、不能作什么
在权限管理以前,还得对用户进行受权,受权后根据权限区分用户
授予和权限认证就是SpringSecurity主要作的事情
很重要的一点是,在SpringBoot中使用,可让本来对开发者来讲复杂的SpringSecurity变得简单易用
固然SpringSecurity也有很明显的缺点,就是导入依赖以后,就默认实现了不少奇奇怪怪的东西,让人感受莫名其妙html
这里是直接在SpringBoot中集成的java
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
二、建立一个Controller类测试一下,因此还要导入web依赖包web
SecretController.javaspring
1 import org.springframework.web.bind.annotation.GetMapping; 2 import org.springframework.web.bind.annotation.RestController; 3 4 @RestController 5 public class SecretController { 6 @GetMapping("/secret") 7 public String getSecret(){ 8 return "this is secret"; 9 } 10 }
而后运行项目咱们直接访问 http://localhost:8080/secret ,会发现页面重定向了,跳转到了一个登录页面数据库
咱们甚至没有设置登录用户名和密码apache
这个地方SpringSecurity默认的用户名是user,密码是动态生成的,在日志中会显示安全
这就是SpringSecurity强大的地方,仅仅是导入了依赖包,就默认进行了登录验证,固然这也是弊端,由于咱们根本不知道它是怎么配置的。mvc
上面是SpringSecurity为咱们默认配置的一个登录页面,下面咱们本身进行配置app
这里是整个例子的文件结构还有pom.xml,以及使用了thymeleaf,因此要导入依赖框架
文件结构
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>org.example</groupId> 8 <artifactId>SecurityTest</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>2.5.2</version> 15 </parent> 16 17 <dependencies> 18 <dependency> 19 <groupId>org.springframework.boot</groupId> 20 <artifactId>spring-boot-starter-web</artifactId> 21 </dependency> 22 23 <dependency> 24 <groupId>org.springframework.boot</groupId> 25 <artifactId>spring-boot-starter-thymeleaf</artifactId> 26 </dependency> 27 28 <dependency> 29 <groupId>org.springframework.boot</groupId> 30 <artifactId>spring-boot-starter-security</artifactId> 31 </dependency> 32 </dependencies> 33 34 <properties> 35 <maven.compiler.source>8</maven.compiler.source> 36 <maven.compiler.target>8</maven.compiler.target> 37 </properties> 38 39 </project>
首先咱们要本身建立一个login页面,以及登陆之后访问的页面
login.html
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" 3 xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 4 <head> 5 <title>Spring Security Example </title> 6 </head> 7 <body> 8 <div th:if="${param.error}"> 9 Invalid username and password. 10 </div> 11 <div th:if="${param.logout}"> 12 You have been logged out. 13 </div> 14 <form th:action="@{/login}" method="post"> 15 <div><label> User Name : <input type="text" name="username"/> </label></div> 16 <div><label> Password: <input type="password" name="password"/> </label></div> 17 <div><input type="submit" value="Sign In"/></div> 18 </form> 19 </body> 20 </html>
hello.html
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" 3 xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 4 <head> 5 <title>Hello World!</title> 6 </head> 7 <body> 8 <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1> 9 10 </body> 11 </html>
而后再MVC里面配置一下这两个页面,才能够经过url进行访问,MVC的配置须要实现WebMvcConfigurer接口
MvcConfig.java
1 import org.springframework.context.annotation.Configuration; 2 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 3 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 4 5 @Configuration 6 public class MvcConfig implements WebMvcConfigurer { 7 8 @Override 9 public void addViewControllers(ViewControllerRegistry registry) { 10 11 registry.addViewController("/").setViewName("login"); 12 registry.addViewController("/hello").setViewName("hello"); 13 registry.addViewController("/login").setViewName("login"); 14 } 15 }
而后咱们须要进行SpringSecurity的配置,定义页面访问请求时,用户须要哪些权限,须要继承WebSecurityConfigurerAdapter类进行配置
如今配置中本身定义了一个用户(在实际项目中从数据库获取),而再也不是由SpringSecurity默认定义
WebSecurityConfig.java
1 import org.springframework.context.annotation.Bean; 2 import org.springframework.context.annotation.Configuration; 3 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 4 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 5 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 6 import org.springframework.security.core.userdetails.User; 7 import org.springframework.security.core.userdetails.UserDetails; 8 import org.springframework.security.core.userdetails.UserDetailsService; 9 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 10 import org.springframework.security.crypto.password.PasswordEncoder; 11 import org.springframework.security.provisioning.InMemoryUserDetailsManager; 12 13 @Configuration 14 @EnableWebSecurity 15 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 16 /* 17 @EnableWebSecurity注解让springsecurity集成springmvc 18 */ 19 @Override 20 protected void configure(HttpSecurity http) throws Exception { 21 /* 22 定义了哪些路径访问是须要权限的,哪些不用 23 /和/login两个url是不须要权限就能够访问的 24 /hello须要有“USER”权限才可以访问 25 */ 26 http.authorizeRequests() 27 .antMatchers("/hello") 28 .hasRole("USER") 29 .and() 30 .formLogin() 31 .loginPage("/login") 32 .permitAll(); 33 } 34 35 36 @Bean 37 public PasswordEncoder passwordEncoder(){ 38 /* 39 声明一个加密工具的Bean,供用户进行加密时调用 40 */ 41 return new BCryptPasswordEncoder(); 42 } 43 44 @Bean 45 @Override 46 protected UserDetailsService userDetailsService() { 47 /* 48 设置了一个预先存储在系统中的用户 49 赋予用户“USER”角色权限,才可以访问hello页面 50 */ 51 String username = "user"; 52 String password = "password"; 53 UserDetails user = User.withUsername(username).password(new BCryptPasswordEncoder().encode(password)).roles("USER").build(); 54 return new InMemoryUserDetailsManager(user); 55 } 56 }
如今运行项目,在没有登陆以前,访问/hello会被重定向到login页面,登陆以后就能访问hello页面了
若是把上面代码里,用户的角色权限“USER”改为其余的,登陆以后访问\hello则会抛出403错误,由于权限不够