本文带领读者体验springboot security的魅力:借助自动配置能力只需要简单几步就能将接口纳入权限管控。
第一步 创建项目
如上图,为了更好地演示配置过程,创建一个空项目。
注意jdk版本需要17及以上。
第二步 配置spring boot 依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhy</groupId>
<artifactId>SpringSecurityDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<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>
</dependencies>
</project>
注意到spring-boot-starter-parent的版本设置为3.0.1(当前最新版本)。
然后添加了spring-boot-starter-web和spring-boot-starter-security的引用,但是这里没指定它俩的版本号,而是跟随parent的版本。
最后实际引入的依赖如下图:
第三步 例行公事:hello world
/**
* @author wanzhouyi
* @date 2023/2/5
*/
@RestController
public class HiController {
@GetMapping("/hi")
public String hi(){
return "hello, world!";
}
}
第四步 启动应用
D:\program\Java\jdk17.0.5\bin\java.exe "
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.1)
2023-02-05T01:17:06.277+08:00 INFO 16812 --- [ main] com.zhy.SpringSecurityApp : Starting SpringSecurityApp using Java 17.0.5 with PID 16812 (D:\testproj\TestSpringSecurity\SpringSecurityDemo\target\classes started by mango in D:\testproj\TestSpringSecurity\SpringSecurityDemo)
2023-02-05T01:17:06.287+08:00 INFO 16812 --- [ main] com.zhy.SpringSecurityApp : No active profile set, falling back to 1 default profile: "default"
2023-02-05T01:17:09.872+08:00 INFO 16812 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-02-05T01:17:09.893+08:00 INFO 16812 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-02-05T01:17:09.894+08:00 INFO 16812 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.4]
2023-02-05T01:17:10.110+08:00 INFO 16812 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-02-05T01:17:10.114+08:00 INFO 16812 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3679 ms
2023-02-05T01:17:10.769+08:00 WARN 16812 --- [ main] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 5f7d42aa-66d8-4a5b-a8fc-81bacab14266
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2023-02-05T01:17:10.909+08:00 INFO 16812 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@36aa52d2, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4ee25d80, org.springframework.security.web.context.SecurityContextHolderFilter@3b705be7, org.springframework.security.web.header.HeaderWriterFilter@43984213, org.springframework.security.web.csrf.CsrfFilter@5b275811, org.springframework.security.web.authentication.logout.LogoutFilter@135a8c6f, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@43bf5397, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@23a918c7, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@16a35bd, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@3679d92e, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@43acd79e, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6fbb4061, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@ba17be6, org.springframework.security.web.access.ExceptionTranslationFilter@e11ecfa, org.springframework.security.web.access.intercept.AuthorizationFilter@42aae04d]
2023-02-05T01:17:11.057+08:00 INFO 16812 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-02-05T01:17:11.081+08:00 INFO 16812 --- [ main] com.zhy.SpringSecurityApp : Started SpringSecurityApp in 6.01 seconds (process running for 7.351)
这里注意到spring boot security给我们默认创建了一个密码(每次都不一样),这个密码只是测试过程使用,但现在我们默默地记住它(用记事本-_-)。
当我们访问localhost:8080/hi并期望应用对我们说“hello world”的时候,实际显示的却是登录页面,如下图所示:
当输入默认的用户(用户名就是user)和随机密码后,成功地看到了spring boot demo说出的hello world。
发生了什么
打开控制台看到:
- 在浏览器地址栏中输入http://localhost:8080/hi,要求访问/hi这个路径
- 请求到达服务端后,发现未携带有效的认证信息
- 服务端要求返回了302状态码,要求客户端重定向到/login页面
- 客户端重新请求http://localhost:8080/login
- 输入用户名和密码后认证成功
- 成功访问/hi接口