這篇文章主要介紹“怎么使用Spring Security”,在日常操作中,相信很多人在怎么使用Spring Security問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”怎么使用Spring Security”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
從網(wǎng)站建設(shè)到定制行業(yè)解決方案,為提供做網(wǎng)站、網(wǎng)站制作服務(wù)體系,各種行業(yè)企業(yè)客戶提供網(wǎng)站建設(shè)解決方案,助力業(yè)務(wù)快速發(fā)展。創(chuàng)新互聯(lián)建站將不斷加快創(chuàng)新步伐,提供優(yōu)質(zhì)的建站服務(wù)。
在 Web 開(kāi)發(fā)中,安全一直是非常重要的一個(gè)方面。安全雖然屬于應(yīng)用的非功能性需求,但是應(yīng)該在應(yīng)用開(kāi)發(fā)的初期就考慮進(jìn)來(lái)。如果在應(yīng)用開(kāi)發(fā)的后期才考慮安全的問(wèn)題,就可能陷入一個(gè)兩難的境地:
1、一方面,應(yīng)用存在嚴(yán)重的安全漏洞,無(wú)法滿足用戶的要求,并可能造成用戶的隱私數(shù)據(jù)被攻擊者竊??;
2、另一方面,應(yīng)用的基本架構(gòu)已經(jīng)確定,要修復(fù)安全漏洞,可能需要對(duì)系統(tǒng)的架構(gòu)做出比較重大的調(diào)整,因而需要更多的開(kāi)發(fā)時(shí)間,影響應(yīng)用的發(fā)布進(jìn)程。因此,從應(yīng)用開(kāi)發(fā)的第一天就應(yīng)該把安全相關(guān)的因素考慮進(jìn)來(lái),并在整個(gè)應(yīng)用的開(kāi)發(fā)過(guò)程中。
市面上存在比較有名的:Shiro,Spring Security!
這里需要闡述一下的是,每一個(gè)框架的出現(xiàn)都是為了解決某一問(wèn)題而產(chǎn)生了,那么Spring Security 框架的出現(xiàn)是為了解決什么問(wèn)題呢?
首先我們看下它的官網(wǎng)介紹:Spring Security官網(wǎng)地址
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements
Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問(wèn)控制框架。它實(shí)際上是保護(hù)基于spring的應(yīng)用程序的標(biāo)準(zhǔn)。
Spring Security是一個(gè)框架,側(cè)重于為Java應(yīng)用程序提供身份驗(yàn)證和授權(quán)。與所有Spring項(xiàng)目一樣,Spring安全性的真正強(qiáng)大之處在于它可以輕松地?cái)U(kuò)展以滿足定制需求
從官網(wǎng)的介紹中可以知道這是一個(gè)權(quán)限框架。想我們之前做項(xiàng)目是沒(méi)有使用框架是怎么控制權(quán)限的?對(duì)于權(quán)限 一般會(huì)細(xì)分為
功能權(quán)限
訪問(wèn)權(quán)限
菜單權(quán)限
各種權(quán)限寫起來(lái)用Filter來(lái)寫會(huì)導(dǎo)致代碼非常的繁瑣,冗余。
怎么解決之前寫權(quán)限代碼繁瑣,冗余的問(wèn)題,一些主流框架就應(yīng)運(yùn)而生而Spring Scecurity就是其中的一種。
Spring 是一個(gè)非常流行和成功的 Java 應(yīng)用開(kāi)發(fā)框架。Spring Security 基于 Spring 框架,提供了一套 Web 應(yīng)用安全性的完整解決方案。一般來(lái)說(shuō),Web 應(yīng)用的安全性包括用戶認(rèn)證(Authentication)和用戶授權(quán)(Authorization)兩個(gè)部分。用戶認(rèn)證指的是驗(yàn)證某個(gè)用戶是否為系統(tǒng)中的合法主體,也就是說(shuō)用戶能否訪問(wèn)該系統(tǒng)。用戶認(rèn)證一般要求用戶提供用戶名和密碼。系統(tǒng)通過(guò)校驗(yàn)用戶名和密碼來(lái)完成認(rèn)證過(guò)程。用戶授權(quán)指的是驗(yàn)證某個(gè)用戶是否有權(quán)限執(zhí)行某個(gè)操作。在一個(gè)系統(tǒng)中,不同用戶所具有的權(quán)限是不同的。比如對(duì)一個(gè)文件來(lái)說(shuō),有的用戶只能進(jìn)行讀取,而有的用戶可以進(jìn)行修改。一般來(lái)說(shuō),系統(tǒng)會(huì)為不同的用戶分配不同的角色,而每個(gè)角色則對(duì)應(yīng)一系列的權(quán)限。
對(duì)于上面提到的兩種應(yīng)用情景,Spring Security 框架都有很好的支持。
1、 在用戶認(rèn)證方面,Spring Security 框架支持主流的認(rèn)證方式,包括 HTTP 基本認(rèn)證、HTTP 表單驗(yàn)證、HTTP 摘要認(rèn)證、OpenID 和 LDAP 等。
2、 在用戶授權(quán)方面,Spring Security 提供了基于角色的訪問(wèn)控制和訪問(wèn)控制列表(Access Control List,ACL),可以對(duì)應(yīng)用中的領(lǐng)域?qū)ο筮M(jìn)行細(xì)粒度的控制。
1、新建一個(gè)初始的springboot項(xiàng)目web模塊,thymeleaf模塊
2、導(dǎo)入靜態(tài)資源
welcome.html |views |level1 1.html 2.html 3.html |level2 1.html 2.html 3.html |level3 1.html 2.html 3.html Login.html
3、controller跳轉(zhuǎn)!
package com.sowhat.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class RouterController { @RequestMapping({"/","/index"}) public String index(){ return "index"; } @RequestMapping("/toLogin") public String toLogin(){ return "views/login"; } @RequestMapping("/level1/{id}") public String level1(@PathVariable("id") int id){ return "views/level1/"+id; } @RequestMapping("/level2/{id}") public String level2(@PathVariable("id") int id){ return "views/level2/"+id; } @RequestMapping("/level3/{id}") public String level3(@PathVariable("id") int id){ return "views/level3/"+id; } }
4、測(cè)試實(shí)驗(yàn)環(huán)境是否OK!
Spring Security 是針對(duì)Spring項(xiàng)目的安全框架,也是Spring Boot底層安全模塊默認(rèn)的技術(shù)選型,他可以實(shí)現(xiàn)強(qiáng)大的Web安全控制,對(duì)于安全控制,我們僅需要引入 spring-boot-starter-security 模塊,進(jìn)行少量的配置,即可實(shí)現(xiàn)強(qiáng)大的安全管理!
記住幾個(gè)類:
WebSecurityConfigurerAdapter:自定義Security策略
AuthenticationManagerBuilder:自定義認(rèn)證策略
@EnableWebSecurity:開(kāi)啟WebSecurity模式
Spring Security的兩個(gè)主要目標(biāo)是 認(rèn)證 和 授權(quán)(訪問(wèn)控制)。
認(rèn)證(Authentication)
身份驗(yàn)證是關(guān)于驗(yàn)證您的憑據(jù),如用戶名/用戶ID和密碼,以驗(yàn)證您的身份。
身份驗(yàn)證通常通過(guò)用戶名和密碼完成,有時(shí)與身份驗(yàn)證因素結(jié)合使用。
授權(quán) (Authorization)
授權(quán)發(fā)生在系統(tǒng)成功驗(yàn)證您的身份后,最終會(huì)授予您訪問(wèn)資源(如信息,文件,數(shù)據(jù)庫(kù),資金,位置,幾乎任何內(nèi)容)的完全權(quán)限。
這個(gè)概念是通用的,而不是只在Spring Security 中存在。
目前,我們的測(cè)試環(huán)境,是誰(shuí)都可以訪問(wèn)的,我們使用 Spring Security 增加上認(rèn)證和授權(quán)的功能
1、引入 Spring Security 模塊
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
2、編寫 Spring Security 配置類
參考官網(wǎng):https://spring.io/projects/spring-security
查看我們自己項(xiàng)目中的版本,找到對(duì)應(yīng)的幫助文檔:文檔
3、編寫基礎(chǔ)配置類
package com.sowhat.config; 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; @EnableWebSecurity // 開(kāi)啟WebSecurity模式 public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { } }
4、定制請(qǐng)求的授權(quán)規(guī)則 configure方法內(nèi)容自定義。
@Override protected void configure(HttpSecurity http) throws Exception { // 定制請(qǐng)求的授權(quán)規(guī)則 // 首頁(yè)所有人可以訪問(wèn),其余的需要有角色權(quán)限才可以訪問(wèn) http.authorizeRequests().antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); }
5、測(cè)試一下:發(fā)現(xiàn)除了首頁(yè)都進(jìn)不去了!因?yàn)槲覀兡壳皼](méi)有登錄的角色,因?yàn)檎?qǐng)求需要登錄的角色擁有對(duì)應(yīng)的權(quán)限才可以!
6、在configure()方法中加入以下配置,如果沒(méi)有權(quán)限訪問(wèn)若干網(wǎng)址則直接跳轉(zhuǎn)到登陸頁(yè)面!formLogin
// 開(kāi)啟自動(dòng)配置的登錄功能 // /login 請(qǐng)求來(lái)到登錄頁(yè) // /login?error 重定向到這里表示登錄失敗 http.formLogin();
7、測(cè)試一下:發(fā)現(xiàn),沒(méi)有權(quán)限的時(shí)候,會(huì)跳轉(zhuǎn)到登錄的頁(yè)面(SpringSecurity 自帶登陸頁(yè)面)!
8、查看剛才登錄頁(yè)的注釋信息;
我們可以定義認(rèn)證規(guī)則,重寫configure(AuthenticationManagerBuilder auth)方法
//定義認(rèn)證規(guī)則 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //在內(nèi)存中定義,也可以在jdbc中去拿.... auth.inMemoryAuthentication() .withUser("sowhat").password("123456").roles("vip2","vip3") .and() .withUser("root").password("123456").roles("vip1","vip2","vip3") .and() .withUser("guest").password("123456").roles("vip1","vip2"); }
9、測(cè)試,我們可以使用這些賬號(hào)登錄進(jìn)行測(cè)試!發(fā)現(xiàn)會(huì)報(bào)錯(cuò)!
There is no PasswordEncoder mapped for the id “null”
10、原因,我們要將前端傳過(guò)來(lái)的密碼進(jìn)行某種方式加密,否則就無(wú)法登錄,修改代碼
//定義認(rèn)證規(guī)則 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //在內(nèi)存中定義,也可以在jdbc中去拿.... //Spring security 5.0中新增了多種加密方式,也改變了密碼的格式。 //要想我們的項(xiàng)目還能夠正常登陸,需要修改一下configure中的代碼。我們要將前端傳過(guò)來(lái)的密碼進(jìn)行某種方式加密 //spring security 官方推薦的是使用bcrypt加密方式。 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("sowhat").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3") .and() .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3") .and() .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2"); }
11、測(cè)試,發(fā)現(xiàn),登錄成功,并且每個(gè)角色只能訪問(wèn)自己認(rèn)證下的規(guī)則!搞定
1、開(kāi)啟自動(dòng)配置的注銷的功能
//定制請(qǐng)求的授權(quán)規(guī)則 @Override protected void configure(HttpSecurity http) throws Exception { //.... //開(kāi)啟自動(dòng)配置的注銷的功能 // /logout 注銷請(qǐng)求 http.logout(); }
2、我們?cè)谇岸?,增加一個(gè)注銷的按鈕(系統(tǒng)自帶的登陸頁(yè)面),index.html 導(dǎo)航欄中
<a class="item" th:href="@{/logout}"> <i class="address card icon"></i> 注銷 </a>
3、我們可以去測(cè)試一下,登錄成功后點(diǎn)擊注銷,發(fā)現(xiàn)注銷完畢會(huì)跳轉(zhuǎn)到登錄頁(yè)面!
4、但是,我們想讓他注銷成功后,依舊可以跳轉(zhuǎn)到首頁(yè),該怎么處理呢?
// .logoutSuccessUrl("/"); 注銷成功來(lái)到首頁(yè) http.logout().logoutSuccessUrl("/");
5、測(cè)試,注銷完畢后,發(fā)現(xiàn)跳轉(zhuǎn)到自定義的首頁(yè)OK
6、我們現(xiàn)在又來(lái)一個(gè)需求:用戶沒(méi)有登錄的時(shí)候,導(dǎo)航欄上只顯示登錄按鈕,用戶登錄之后,導(dǎo)航欄可以顯示登錄的用戶信息及注銷按鈕!還有就是,比如sowhat這個(gè)用戶,它只有 vip2,vip3功能,那么登錄則只顯示這兩個(gè)功能,而vip1的功能菜單不顯示!這個(gè)就是真實(shí)的網(wǎng)站情況了!該如何做呢?
我們需要結(jié)合thymeleaf中的一些功能
sec:authorize="isAuthenticated()":是否認(rèn)證登錄!來(lái)顯示不同的頁(yè)面
Maven依賴:
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 --> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> <version>3.0.4.RELEASE</version> </dependency>
7、修改我們的 前端頁(yè)面
導(dǎo)入命名空間
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
修改導(dǎo)航欄,增加認(rèn)證判斷
<!--登錄注銷--> <div class="right menu"> <!--如果未登錄--> <div sec:authorize="!isAuthenticated()"> <a class="item" th:href="@{/login}"> <i class="address card icon"></i> 登錄 </a> </div> <!--如果已登錄--> <div sec:authorize="isAuthenticated()"> <a class="item"> <i class="address card icon"></i> 用戶名:<span sec:authentication="principal.username"></span> 角色:<span sec:authentication="principal.authorities"></span> </a> </div> <div sec:authorize="isAuthenticated()"> <a class="item" th:href="@{/logout}"> <i class="address card icon"></i> 注銷 </a> </div> </div>
8、重啟測(cè)試,我們可以登錄試試看,登錄成功后確實(shí),顯示了我們想要的頁(yè)面;
9、如果注銷404了,就是因?yàn)樗J(rèn)防止csrf跨站請(qǐng)求偽造,因?yàn)闀?huì)產(chǎn)生安全問(wèn)題,我們可以將請(qǐng)求改為post表單提交,或者在spring security中關(guān)閉csrf功能;我們?cè)囋嚕涸?配置中增加 http.csrf().disable();
http.csrf().disable();//關(guān)閉csrf功能:跨站請(qǐng)求偽造,默認(rèn)只能通過(guò)post方式提交logout請(qǐng)求 http.logout().logoutSuccessUrl("/");
10、我們繼續(xù)將下面的角色功能塊認(rèn)證完成!
<!-- sec:authorize="hasRole('vip1')">
11、測(cè)試一下!
12、權(quán)限控制和注銷搞定!
現(xiàn)在的情況,我們只要登錄之后,關(guān)閉瀏覽器,再登錄,就會(huì)讓我們重新登錄,但是很多網(wǎng)站的情況,就是有一個(gè)記住密碼的功能,這個(gè)該如何實(shí)現(xiàn)呢?很簡(jiǎn)單
1、開(kāi)啟記住我功能
//定制請(qǐng)求的授權(quán)規(guī)則 @Override protected void configure(HttpSecurity http) throws Exception { //。。。。。。。。。。。 //記住我 http.rememberMe(); }
2、我們?cè)俅螁?dòng)項(xiàng)目測(cè)試一下,發(fā)現(xiàn)登錄頁(yè)多了一個(gè)記住我功能,我們登錄之后關(guān)閉 瀏覽器,然后重新打開(kāi)瀏覽器訪問(wèn),發(fā)現(xiàn)用戶依舊存在!
思考:如何實(shí)現(xiàn)的呢?其實(shí)非常簡(jiǎn)單,我們可以查看瀏覽器的cookie
3、我們點(diǎn)擊注銷的時(shí)候,可以發(fā)現(xiàn),spring security 幫我們自動(dòng)刪除了這個(gè) cookie
4、結(jié)論:登錄成功后,將cookie發(fā)送給瀏覽器保存,以后登錄帶上這個(gè)cookie,只要通過(guò)檢查就可以免登錄了。如果點(diǎn)擊注銷,則會(huì)刪除這個(gè)cookie,具體的原理跟JavaWeb階段一樣(默認(rèn)保存14天)!也可以參考 此文
現(xiàn)在這個(gè)登錄頁(yè)面都是spring security 默認(rèn)的,怎么樣可以使用我們自己寫的Login界面呢?
1、在剛才的登錄頁(yè)配置后面指定 loginpage
http.formLogin().loginPage("/toLogin");
2、然后前端也需要指向我們自己定義的 login請(qǐng)求
<a class="item" th:href="@{/toLogin}"> <i class="address card icon"></i> 登錄 </a>
3、我們登錄,需要將這些信息發(fā)送到哪里,我們也需要配置,login.html 配置提交請(qǐng)求及方式,方式必須為post:
在 loginPage()源碼中的注釋上有寫明:
<form th:action="@{/login}" method="post"> <div class="field"> <label>Username</label> <div class="ui left icon input"> <input type="text" placeholder="Username" name="username"> <i class="user icon"></i> </div> </div> <div class="field"> <label>Password</label> <div class="ui left icon input"> <input type="password" name="password"> <i class="lock icon"></i> </div> </div> <input type="submit" class="ui blue submit button"/> </form>
4、這個(gè)請(qǐng)求提交上來(lái),我們還需要驗(yàn)證處理,怎么做呢?我們可以查看formLogin()方法的源碼!我們配置接收登錄的用戶名和密碼的參數(shù)!
http.formLogin() .usernameParameter("username") .passwordParameter("password") .loginPage("/toLogin") .loginProcessingUrl("/login"); // 登陸表單提交請(qǐng)求
5、在登錄頁(yè)增加記住我的多選框
<input type="checkbox" name="remember"> 記住我
6、后端驗(yàn)證處理!
//定制記住我的參數(shù)! http.rememberMe().rememberMeParameter("remember");
package com.sowhat.config; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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.crypto.bcrypt.BCryptPasswordEncoder; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { //定制請(qǐng)求的授權(quán)規(guī)則 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); //開(kāi)啟自動(dòng)配置的登錄功能:如果沒(méi)有權(quán)限,就會(huì)跳轉(zhuǎn)到登錄頁(yè)面! // /login 請(qǐng)求來(lái)到登錄頁(yè) // /login?error 重定向到這里表示登錄失敗 http.formLogin() .usernameParameter("username") .passwordParameter("password") .loginPage("/toLogin") .loginProcessingUrl("/login"); // 登陸表單提交請(qǐng)求 //開(kāi)啟自動(dòng)配置的注銷的功能 // /logout 注銷請(qǐng)求 // .logoutSuccessUrl("/"); 注銷成功來(lái)到首頁(yè) http.csrf().disable();//關(guān)閉csrf功能:跨站請(qǐng)求偽造,默認(rèn)只能通過(guò)post方式提交logout請(qǐng)求 http.logout().logoutSuccessUrl("/"); //記住我 http.rememberMe().rememberMeParameter("remember"); } //定義認(rèn)證規(guī)則 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //在內(nèi)存中定義,也可以在jdbc中去拿.... //Spring security 5.0中新增了多種加密方式,也改變了密碼的格式。 //要想我們的項(xiàng)目還能夠正常登陸,需要修改一下configure中的代碼。我們要將前端傳過(guò)來(lái)的密碼進(jìn)行某種方式加密 //spring security 官方推薦的是使用bcrypt加密方式。 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("sowhat").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3") .and() .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3") .and() .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2"); } }
到此,關(guān)于“怎么使用Spring Security”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
網(wǎng)頁(yè)題目:怎么使用SpringSecurity
文章地址:http://aaarwkj.com/article32/jjgisc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、動(dòng)態(tài)網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、做網(wǎng)站、網(wǎng)站設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)