??<前文回顧>
<今日更新>
一、開篇整活兒
今兒個咱嘮嘮 Spring Boot 里頭的安全性。這玩意兒吧,說大不大,說小不小,整好了是錦上添花,整不好就是火上澆油。你要是剛入門,那可得悠著點兒,別一上來就整得自己“翻車”了。
二、安全性是啥玩意兒?
安全性是系統開發里頭的一個核心問題,說白了就是保證系統的數據和操作不被非法訪問。Spring Boot 里頭默認就集成了安全性,用起來賊方便。
1. 認證與授權
安全性里頭有兩個核心概念:認證(Authentication)和授權(Authorization)。
- 認證:就是驗證用戶的身份,比如說用戶名和密碼。
- 授權:就是驗證用戶的權限,比如說某個用戶能不能訪問某個資源。
2. Spring Security 是啥玩意兒?
Spring Security 是 Spring 里頭的一個安全性框架,專門用來實現認證和授權。Spring Boot 里頭默認就集成了 Spring Security,用起來賊方便。
三、Spring Boot 集成 Spring Security
Spring Boot 里頭集成 Spring Security 很簡單,只要加個依賴,配個安全性配置就行了。
1. 添加依賴
首先,你得在?pom.xml?里頭加個 Spring Security 的依賴。
XML Code |
<dependency> ????<groupId>org.springframework.boot</groupId> ????<artifactId>spring-boot-starter-security</artifactId> </dependency> |
這段代碼里頭,spring-boot-starter-security?是 Spring Boot 里頭的 Spring Security 依賴。
2. 配置安全性
然后,你得在?application.properties?里頭配個安全性配置。
Properties Code |
spring.security.user.name=admin spring.security.user.password=admin |
這段代碼里頭,spring.security.user.name?是默認的用戶名,spring.security.user.password?是默認的密碼。
3. 使用 Spring Security
最后,你可以在代碼里頭用 Spring Security 來實現認證和授權。
Java Code |
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ????@Override ????protected void configure(HttpSecurity http) throws Exception { ????????http.authorizeRequests() ????????????????.antMatchers("/public/**").permitAll() ????????????????.anyRequest().authenticated() ????????????????.and() ????????????????.formLogin(); ????} } |
這段代碼里頭,SecurityConfig?類繼承了?WebSecurityConfigurerAdapter,重寫了?configure?方法,配置了安全性。
四、Spring Boot 使用 JWT 實現認證
JWT(JSON Web Token)是一種開放標準(RFC 7519),用來在各方之間安全地傳輸信息。Spring Boot 里頭使用 JWT 實現認證很簡單,只要加個依賴,配個 JWT 配置就行了。
1. 添加依賴
首先,你得在?pom.xml?里頭加個 JWT 的依賴。
Java Code |
<dependency> ????<groupId>io.jsonwebtoken</groupId> ????<artifactId>jjwt</artifactId> ????<version>0.9.1</version> </dependency> |
這段代碼里頭,jjwt?是 JWT 的依賴。
2. 配置 JWT
然后,你得在?application.properties?里頭配個 JWT 配置。
Properties Code |
jwt.secret=mySecret jwt.expiration=86400 |
這段代碼里頭,jwt.secret?是 JWT 的密鑰,jwt.expiration?是 JWT 的過期時間。
3. 生成 JWT
最后,你可以在代碼里頭生成 JWT。
Java Code |
@Service public class JwtService { ????@Value("${jwt.secret}") ????private String secret; ????@Value("${jwt.expiration}") ????private long expiration; ????public String generateToken(String username) { ????????return Jwts.builder() ????????????????.setSubject(username) ????????????????.setExpiration(new Date(System.currentTimeMillis() + expiration * 1000)) ????????????????.signWith(SignatureAlgorithm.HS512, secret) ????????????????.compact(); ????} } |
這段代碼里頭,generateToken?方法用?Jwts.builder?生成了一個 JWT。
五、Spring Boot 使用 JWT 實現授權
Spring Boot 里頭使用 JWT 實現授權很簡單,只要加個過濾器,配個授權配置就行了。
1. 添加過濾器
首先,你得在代碼里頭加個 JWT 過濾器。
Java Code |
@Component public class JwtFilter extends OncePerRequestFilter { ????@Autowired ????private JwtService jwtService; ????@Override ????protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ????????String token = request.getHeader("Authorization"); ????????if (token != null && jwtService.validateToken(token)) { ????????????String username = jwtService.getUsernameFromToken(token); ????????????UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()); ????????????SecurityContextHolder.getContext().setAuthentication(authentication); ????????} ????????filterChain.doFilter(request, response); ????} } |
這段代碼里頭,JwtFilter?類繼承了?OncePerRequestFilter,重寫了?doFilterInternal?方法,實現了 JWT 過濾器。
2. 配置授權
然后,你得在?SecurityConfig?里頭配個授權配置。
Java Code |
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ????@Autowired ????private JwtFilter jwtFilter; ????@Override ????protected void configure(HttpSecurity http) throws Exception { ????????http.authorizeRequests() ????????????????.antMatchers("/public/**").permitAll() ????????????????.anyRequest().authenticated() ????????????????.and() ????????????????.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); ????} } |
這段代碼里頭,addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)?表示在?UsernamePasswordAuthenticationFilter?之前添加?JwtFilter。
六、Spring Boot 使用 Spring Security 的坑點
1. 安全性配置不對
Spring Boot 里頭,安全性配置不對,那認證和授權就不起作用了。你要是沒配好,那可得好好檢查檢查。
Java Code |
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ????@Override ????protected void configure(HttpSecurity http) throws Exception { ????????http.authorizeRequests() ????????????????.antMatchers("/public/**").permitAll() ????????????????.anyRequest().authenticated() ????????????????.and() ????????????????.formLogin(); ????} } |
這段代碼里頭,antMatchers("/public/**").permitAll()?表示?/public/**?路徑下的資源不需要認證。
2. JWT 配置不對
Spring Boot 里頭,JWT 配置不對,那認證和授權就不起作用了。你要是沒配好,那可得好好檢查檢查。
Properties Code |
jwt.secret=mySecret jwt.expiration=86400 |
這段代碼里頭,jwt.secret?和?jwt.expiration?是 JWT 的配置。
3. 過濾器順序不對
Spring Boot 里頭,過濾器順序不對,那認證和授權就不起作用了。你要是沒配好,那可得好好調整調整。
Java Code |
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ????@Autowired ????private JwtFilter jwtFilter; ????@Override ????protected void configure(HttpSecurity http) throws Exception { ????????http.authorizeRequests() ????????????????.antMatchers("/public/**").permitAll() ????????????????.anyRequest().authenticated() ????????????????.and() ????????????????.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); ????} } |
這段代碼里頭,addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)?表示在?UsernamePasswordAuthenticationFilter?之前添加?JwtFilter。
專有名詞解釋
- 安全性:系統開發里頭的一個核心問題,保證系統的數據和操作不被非法訪問。
- 認證:驗證用戶的身份,比如說用戶名和密碼。
- 授權:驗證用戶的權限,比如說某個用戶能不能訪問某個資源。
- Spring Security:Spring 里頭的一個安全性框架,專門用來實現認證和授權。
- JWT:JSON Web Token,一種開放標準,用來在各方之間安全地傳輸信息。
- Jwts.builder:JWT 的一個類,用來生成 JWT。
- OncePerRequestFilter:Spring 里頭的一個類,用來實現過濾器。
- UsernamePasswordAuthenticationToken:Spring Security 里頭的一個類,用來表示用戶名和密碼的認證信息。
- SecurityContextHolder:Spring Security 里頭的一個類,用來保存安全性上下文。
- addFilterBefore:Spring Security 里頭的一個方法,用來添加過濾器。
=======================================================================
寫在最后
身為一個中古程序猿,我有很多自己想做的事情,比如埋頭苦干手搓一個低代碼數據庫設計平臺(目前只針對寫java的朋友),已經在找朋友內測了,比如很喜歡幫身邊的朋友看看簡歷,講講面試技巧,畢竟工作這么多年,也做到過高管,有很多面人經歷,意見還算有用,大家基本都能拿到想要的offer...
我深刻意識到,能自由做自己喜歡的事情是有多么不容易,又是多么有成就感。所以我拉了兩三個志同道合的好友,開了一間公司,繼續朝著“自由”的目標前進。
當下呢,我們希望有更多的朋友能夠參與到產品的測試中來,體驗并且給出更好的建議。未來可能會在博客po更多關于我們產品的內容,包括使用場景、說明、課程等,希望能對大家有所幫助。
另外,想整個花活兒,每天花個1-2小時,來幫助我素未謀面的老朋友們看看簡歷,提提意見啥的,純屬為愛發電。我在線時間不固定,但是不要米,咱就別要自行車兒了唄~如果您有興趣,可以點擊文章底部卡片一起交流(人工回復,比較慢,請擔待)。
最后,請大家持續關注我們的博客,未來還有很多欄目,一起發掘~!