最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Security入門demo案例

 更新時間:2021年08月18日 10:08:06   作者:文景大大  
Spring Security是一個高度自定義的安全框架,本文主要介紹了Spring Security入門,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、簡介

Spring Security是一個高度自定義的安全框架。利用Spring IoC/DI和AOP功能,為系統(tǒng)提供了聲明式安全訪問控制功能,減少了為系統(tǒng)安全而編寫大量重復代碼的工作。主要包含如下幾個重要的內(nèi)容:

  • 認證(Authentication),系統(tǒng)認為用戶是否能登錄。
  • 授權(Authorization),系統(tǒng)判斷用戶是否有權限去做某些事情。

二、入門案例

首先引入必要的依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

然后創(chuàng)建一個controller:

@Slf4j
@RestController
public class SecurityController {

    @GetMapping({"/", "/index"})
    public String getLogin() {
        log.info("進入index");
        return "index";
    }

}

此時,我們的入門案例就完成了。啟動項目,Spring Security默認就開啟了,此時訪問localhost:8080/index就會被Spring Security攔截,跳轉到內(nèi)置的登錄頁面要求登錄。

默認情況下,登錄的用戶名為user,密碼在啟動項目的時候,控制臺有打印出來:

Using generated security password: 0bfad04b-7a47-40fb-ae15-2a4a7c57099b

使用如上的賬密登錄后,再次訪問localhost:8080/index就可以正常返回預期的內(nèi)容index了。

如果我們不希望使用默認的用戶密碼,可以在配置文件中指定一個,如此Spring Security就會使用我們指定的,而不會使用默認的了。

spring.security.user.name=zhangxun
spring.security.user.password=123123

三、自定義認證邏輯

當我們開啟自定義認證邏輯后,上面的默認用戶和配置文件中的用戶就不生效了,可以先行刪除。

我們新建一個MySecurityConfig類,并繼承WebSecurityConfigurerAdapter類,用于自定義認證邏輯。

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 指定使用BCryptPasswordEncoder對前端傳過來的明文密碼進行encode
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        // 用戶的真實密碼需要encode,security是比較兩個密文是否一致
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("root").password(encoder.encode("root123")).roles();
    }

}

需要注意的是,密碼必須使用如上的PasswordEncoder進行編碼,否則會拋出如下錯誤:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

此時,我們重啟應用,訪問localhost:8080/index進入內(nèi)置的登錄頁面,輸入root/root123之后就能正常返回index內(nèi)容了。

四、自定義授權邏輯

一般權限管理都是基于RBAC模型的,即登錄的用戶肯定擁有某些角色,這些角色允許訪問某些資源。我們先來改造下認證的邏輯:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    PasswordEncoder encoder = new BCryptPasswordEncoder();
    auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("root").password(encoder.encode("root123")).roles("admin","manager")
        .and()
        .withUser("manager").password(encoder.encode("mm000")).roles("manager");
}

使得root用戶擁有admin和manager兩個角色,zhang用戶擁有manager一個角色。

然后我們在該配置類中再增加自定義授權的邏輯:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        // 任何角色允許訪問
        .antMatchers("/", "/index").permitAll()
        // 僅admin角色可以訪問
        .antMatchers("/admin/**").hasRole("admin")
        // admin和manager兩個角色可以訪問
        .antMatchers("/manager/**").hasAnyRole("admin", "manager");

    // 沒有權限則進入內(nèi)置的登錄頁面
    http.formLogin();
}

然后為了測試,我們還需要增加幾個資源:

@Slf4j
@RestController
public class SecurityController {

    @GetMapping({"/", "/index"})
    public String getLogin() {
        log.info("進入index");
        return "index";
    }

    @GetMapping("admin/getHello")
    public String getAdminHello(){
        return "hello admin!";
    }

    @GetMapping("manager/getHello")
    public String getManagerHello(){
        return "hello manager!";
    }

    @GetMapping("guest/getHello")
    public String getGuestHello(){
        return "hello guest!";
    }

}

此時,重啟項目,我們發(fā)現(xiàn):

  • 訪問/,/index,/guest/**的資源直接就能返回,不需要認證和授權。
  • 訪問/admin/**資源的時候,由于沒有登錄,會跳轉到內(nèi)置的登錄頁面;如果已經(jīng)登錄,只有root用戶登錄后才可以訪問;
  • 訪問/admin/**資源的時候,由于沒有登錄,會跳轉到內(nèi)置的登錄頁面;如果已經(jīng)登錄,那么root和zhang用戶都能訪問;

我們還可以定制自己的登錄頁面,用于替換Spring Security內(nèi)置的登錄頁面,這塊需要定制html頁面,本文不再詳述,比較簡單,可以參考formLogin的源碼注釋,里面講的比較清楚。

五、注銷登錄

因為我們使用的是Spring Security內(nèi)置的登錄頁面,各個資源返回的也是json字符串,并非頁面,所以如何實現(xiàn)注銷登錄是個問題。但可以通過閱讀HttpSecurity:logout中的源碼注釋,我們基本就能學會怎么操作了。

  • 注銷登錄默認就開啟了,默認是訪問/logout,和/login一樣都是Spring Security自己實現(xiàn)的,我們調用即可;
  • 注銷登錄會清除服務器端的session,清除remember me等設置;這個后面再詳細解說;
  • 注銷登錄后默認會跳轉到/login頁面;

還是如上的案例,我們在登錄后,直接調用http://localhost:8080/logout就可以實現(xiàn)上述的注銷登錄功能了。

但是在有些時候,我們會自定義登出的URL以及成功登出后應該跳轉到哪個URL,Spring Security也支持我們進行自定義。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 任何角色允許訪問
                .antMatchers("/", "/index").permitAll()
                // 僅admin角色可以訪問
                .antMatchers("/admin/**").hasRole("admin")
                // admin和manager兩個角色可以訪問
                .antMatchers("/manager/**").hasAnyRole("admin", "manager");

        // 沒有權限進入內(nèi)置的登錄頁面
        http.formLogin();
        // 自定義登出邏輯
        http.logout().logoutUrl("/myLogOut").logoutSuccessUrl("/index");
    }

當Post方式請求/myLogOut的時候就會觸發(fā)Spring Security的登出邏輯,并且登出后會跳轉到/index界面。

注意:在本案例中,是使用瀏覽器進行測試的,而且沒有html的頁面,所以使用瀏覽器發(fā)起post請求比較困難,那么使用get請求發(fā)起可以嗎?默認是不行的,因為Spring Security默認開啟了CSRF校驗,所有改變狀態(tài)的請求都必須以POST方式提交,為了能驗證我們這個例子,我們需要把CSRF校驗關掉,即在如上logout代碼后面加上如下的配置:

// 暫時關閉CSRF校驗,允許get請求登出
http.csrf().disable();

此時再重啟應用,就可以驗證localhost:8080/myLogOut的登出邏輯了。

六、記住我功能

當我們沒有開啟記住我功能的時候,登錄root用戶后,如果關掉瀏覽器,重新打開網(wǎng)址,會發(fā)現(xiàn)登錄已經(jīng)退出了,這是因為登錄信息只在當前會話有效。

如果我們想要在某個時間段以內(nèi),一直使root用戶處于登錄狀態(tài),那么就需要在瀏覽器端設置一個cookie,在有效期內(nèi),這個cookie所屬的用戶就一直是登錄的狀態(tài)。同樣的,只要在上面注銷登錄的代碼后面加上:

// 開啟remember me功能,有效期默認14天
http.rememberMe();

此時內(nèi)置的登錄頁面會出現(xiàn)記住我的選擇框,當我們選擇上登錄后,瀏覽器端就會有當前用戶的cookie信息了(名稱為remember-me),在它過期之前,登錄狀態(tài)就一直有效。

需要用戶主動退出登錄,也就是調用我們上面的/myLogOut才能將cookie清除并退出登錄。

如果是自定義的登錄頁面,可以在后面鏈式調用rememberMeParameter()方法,傳入自己的rememberme參數(shù)名稱即可。

以上是關于Spring Security的基本使用方法,使用數(shù)據(jù)庫及其它特性將會在后面的文章中予以說明。

七、會話管理

在以上例子中,認證和授權都是Spring Security自動進行的。但是有的時候我們需要管理會話,比如從會話中獲取用戶姓名、用戶的權限信息;會話策略選擇以及會話超時設置等。

我們只需要增加如下的方法即可:

    private String getName(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        if(principal == null){
            return "游客";
        }
        if(principal instanceof UserDetails){
            UserDetails userDetails = (UserDetails) principal;
            return userDetails.getUsername();
        } else{
            return principal.toString();
        }
    }

該方法使用SecurityContextHolder獲取上下文信息,然后再獲取到其中的用戶名即可,當然其中還提供了可以獲取密碼、權限信息等方法。

Session的管理策略有以下幾種:

  • always,如果沒有Session就會創(chuàng)建一個;
  • ifRequired,登錄時如果有需要,就創(chuàng)建一個;
  • never,不會主動創(chuàng)建session,如果其它地方創(chuàng)建了session,就會使用它;
  • stateless,不會創(chuàng)建也不會使用session;

其中ifRequired是默認的模式,stateless是采用token機制時,session禁用的模式,設置方法如下:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
    }

至于session的超時和安全可以在配置文件中設置:

# 超時時間設置
server.servlet.session.timeout=3600s
# 瀏覽器腳本將無法訪問cookie
server.servlet.session.cookie.http‐only=true
# cookie將僅通過HTTPS連接發(fā)送
server.servlet.session.cookie.secure=true

到此這篇關于Spring Security入門demo案例的文章就介紹到這了,更多相關Spring Security入門內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Swagger中@ApiIgnore注解的使用詳解

    Swagger中@ApiIgnore注解的使用詳解

    這篇文章主要介紹了Swagger中@ApiIgnore注解的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java 正確地從類路徑中獲取資源

    Java 正確地從類路徑中獲取資源

    Java 有能力從類路徑中查找獲取資源,可將資源放在 CLASSPATH 里,也可打包到 Jar 中。本文將具體講述獲取資源的步驟,感興趣的朋友可以了解下
    2021-05-05
  • linux查找安裝jdk并配置JAVA_HOME的方法

    linux查找安裝jdk并配置JAVA_HOME的方法

    這篇文章主要介紹了linux查找安裝jdk,配置JAVA_HOME,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • 解決Spring國際化文案占位符失效問題的方法

    解決Spring國際化文案占位符失效問題的方法

    本篇文章主要介紹了解決Spring國際化文案占位符失效問題的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Java基礎知識精通塊作用域與條件及switch語句

    Java基礎知識精通塊作用域與條件及switch語句

    塊(block,即復合語句)是指由若干條 Java 語句組成的語句,并由一對大括號括起來。塊確定了變量的作用域。一個塊可以嵌套在另一個塊中;條件語句、switch語句是我們常見會用到的結構,感興趣的朋友來看看吧
    2022-04-04
  • 淺談關于Java正則和轉義中\(zhòng)\和\\\\的理解

    淺談關于Java正則和轉義中\(zhòng)\和\\\\的理解

    這篇文章主要介紹了淺談關于Java正則和轉義中\(zhòng)\和\\\\的理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • Spring Cloud Sleuth整合zipkin過程解析

    Spring Cloud Sleuth整合zipkin過程解析

    這篇文章主要介紹了Spring Cloud Sleuth整合zipkin過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • Java?超詳細講解字符流

    Java?超詳細講解字符流

    字符流就是在字節(jié)流的基礎上,加上編碼,形成的數(shù)據(jù)流,字符流出現(xiàn)的意義是因為字節(jié)流在操作字符時,可能會有中文導致的亂碼,所以由字節(jié)流引申出了字符流
    2022-04-04
  • idea中無法自動裝配未找到 ‘XXXXXXX‘ 類型的 Bean

    idea中無法自動裝配未找到 ‘XXXXXXX‘ 類型的 Bean

    本文主要介紹了idea中無法自動裝配未找到 ‘XXXXXXX‘ 類型的 Bean的原因及三種解決方法,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • 重試框架Guava-Retry和spring-Retry的使用示例

    重試框架Guava-Retry和spring-Retry的使用示例

    spring-retry 和 guava-retry 工具都是線程安全的重試,能夠支持并發(fā)業(yè)務場景的重試邏輯正確性,本文主要介紹了重試框架Guava-Retry和spring-Retry的使用示例,感興趣的可以一下
    2023-09-09

最新評論

南阳市| 吉木乃县| 阜宁县| 黄龙县| 乾安县| 江阴市| 竹溪县| 吉水县| 台安县| 广昌县| 林口县| 辽宁省| 灵山县| 榆社县| 广东省| 怀安县| 开封县| 类乌齐县| 鲁甸县| 德惠市| 堆龙德庆县| 开封县| 亚东县| 广灵县| 苍山县| 株洲市| 屯昌县| 杭州市| 安乡县| 凌源市| 张家界市| 樟树市| 彭阳县| 贵南县| 平陆县| 太保市| 阜宁县| 舒兰市| 定西市| 贺州市| 墨江|