1. 程式人生 > >手把手帶你入門 Spring Security!

手把手帶你入門 Spring Security!

Spring Security 是 Spring 家族中的一個安全管理框架,實際上,在 Spring Boot 出現之前,Spring Security 就已經發展了多年了,但是使用的並不多,安全管理這個領域,一直是 Shiro 的天下。

相對於 Shiro,在 SSM/SSH 中整合 Spring Security 都是比較麻煩的操作,所以,Spring Security 雖然功能比 Shiro 強大,但是使用反而沒有 Shiro 多(Shiro 雖然功能沒有 Spring Security 多,但是對於大部分專案而言,Shiro 也夠用了)。

自從有了 Spring Boot 之後,Spring Boot 對於 Spring Security 提供了 自動化配置方案,可以零配置使用 Spring Security。

因此,一般來說,常見的安全管理技術棧的組合是這樣的:

  • SSM + Shiro
  • Spring Boot/Spring Cloud + Spring Security

注意,這只是一個推薦的組合而已,如果單純從技術上來說,無論怎麼組合,都是可以執行的。

我們來看下具體使用。

1.專案建立

在 Spring Boot 中使用 Spring Security 非常容易,引入依賴即可:

pom.xml 中的 Spring Security 依賴:

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

只要加入依賴,專案的所有介面都會被自動保護起來。

2.初次體驗

我們建立一個 HelloController:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

訪問 /hello ,需要登入之後才能訪問。

當用戶從瀏覽器傳送請求訪問 /hello 介面時,服務端會返回 302 響應碼,讓客戶端重定向到 /login 頁面,使用者在 /login 頁面登入,登陸成功之後,就會自動跳轉到 /hello

介面。

另外,也可以使用 POSTMAN 來發送請求,使用 POSTMAN 傳送請求時,可以將使用者資訊放在請求頭中(這樣可以避免重定向到登入頁面):

通過以上兩種不同的登入方式,可以看出,Spring Security 支援兩種不同的認證方式:

  • 可以通過 form 表單來認證
  • 可以通過 HttpBasic 來認證

3.使用者名稱配置

預設情況下,登入的使用者名稱是 user ,密碼則是專案啟動時隨機生成的字串,可以從啟動的控制檯日誌中看到預設密碼:

這個隨機生成的密碼,每次啟動時都會變。對登入的使用者名稱/密碼進行配置,有三種不同的方式:

  • 在 application.properties 中進行配置
  • 通過 Java 程式碼配置在記憶體中
  • 通過 Java 從資料庫中載入

前兩種比較簡單,第三種程式碼量略大,本文就先來看看前兩種,第三種後面再單獨寫文章介紹,也可以參考我的微人事專案。

3.1 配置檔案配置使用者名稱/密碼

可以直接在 application.properties 檔案中配置使用者的基本資訊:

spring.security.user.name=javaboy
spring.security.user.password=123

配置完成後,重啟專案,就可以使用這裡配置的使用者名稱/密碼登入了。

3.2 Java 配置使用者名稱/密碼

也可以在 Java 程式碼中配置使用者名稱密碼,首先需要我們建立一個 Spring Security 的配置類,整合自 WebSecurityConfigurerAdapter 類,如下:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //下面這兩行配置表示在記憶體中配置了兩個使用者
        auth.inMemoryAuthentication()
                .withUser("javaboy").roles("admin").password("$2a$10$OR3VSksVAmCzc.7WeaRPR.t0wyCsIj24k0Bne8iKWV1o.V9wsP8Xe")
                .and()
                .withUser("lisi").roles("user").password("$2a$10$p1H8iWa8I4.CA.7Z8bwLjes91ZpY.rYREGHQEInNtAp4NzL6PLKxi");
    }
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

這裡我們在 configure 方法中配置了兩個使用者,使用者的密碼都是加密之後的字串(明文是 123),從 Spring5 開始,強制要求密碼要加密,如果非不想加密,可以使用一個過期的 PasswordEncoder 的例項 NoOpPasswordEncoder,但是不建議這麼做,畢竟不安全。

Spring Security 中提供了 BCryptPasswordEncoder 密碼編碼工具,可以非常方便的實現密碼的加密加鹽,相同明文加密出來的結果總是不同,這樣就不需要使用者去額外儲存的欄位了,這一點比 Shiro 要方便很多。

4.登入配置

對於登入介面,登入成功後的響應,登入失敗後的響應,我們都可以在 WebSecurityConfigurerAdapter 的實現類中進行配置。例如下面這樣:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    VerifyCodeFilter verifyCodeFilter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);
        http
        .authorizeRequests()//開啟登入配置
        .antMatchers("/hello").hasRole("admin")//表示訪問 /hello 這個介面,需要具備 admin 這個角色
        .anyRequest().authenticated()//表示剩餘的其他介面,登入之後就能訪問
        .and()
        .formLogin()
        //定義登入頁面,未登入時,訪問一個需要登入之後才能訪問的介面,會自動跳轉到該頁面
        .loginPage("/login_p")
        //登入處理介面
        .loginProcessingUrl("/doLogin")
        //定義登入時,使用者名稱的 key,預設為 username
        .usernameParameter("uname")
        //定義登入時,使用者密碼的 key,預設為 password
        .passwordParameter("passwd")
        //登入成功的處理器
        .successHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("success");
                    out.flush();
                }
            })
            .failureHandler(new AuthenticationFailureHandler() {
                @Override
                public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("fail");
                    out.flush();
                }
            })
            .permitAll()//和表單登入相關的介面統統都直接通過
            .and()
            .logout()
            .logoutUrl("/logout")
            .logoutSuccessHandler(new LogoutSuccessHandler() {
                @Override
                public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("logout success");
                    out.flush();
                }
            })
            .permitAll()
            .and()
            .httpBasic()
            .and()
            .csrf().disable();
    }
}

我們可以在 successHandler 方法中,配置登入成功的回撥,如果是前後端分離開發的話,登入成功後返回 JSON 即可,同理,failureHandler 方法中配置登入失敗的回撥,logoutSuccessHandler 中則配置登出成功的回撥。

5.忽略攔截

如果某一個請求地址不需要攔截的話,有兩種方式實現:

  • 設定該地址匿名訪問
  • 直接過濾掉該地址,即該地址不走 Spring Security 過濾器鏈

推薦使用第二種方案,配置如下:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/vercode");
    }
}

Spring Security 另外一個強大之處就是它可以結合 OAuth2 ,玩出更多的花樣出來,這些我們在後面的文章中再和大家細細介紹。

本文就先說到這裡,有問題歡迎留言討論。

關注公眾號【江南一點雨】,專注於 Spring Boot+微服務以及前後端分離等全棧技術,定期視訊教程分享,關注後回覆 Java ,領取鬆哥為你精心準備的 Java 乾貨!

相關推薦

手把手入門 Spring Security

Spring Security 是 Spring 家族中的一個安全管理框架,實際上,在 Spring Boot 出現之前,Spring Security 就已經發展了多年了,但是使用的並不多,安全管理這個領域,一直是 Shiro 的天下。 相對於 Shiro,在 SSM/SSH 中整合 Spring Sec

Android:手把手入門神祕的 Rxjava

前言 Rxjava由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android開發者的歡迎。 本文主要: 面向 剛接觸Rxjava的初學者 提供了一份 清晰、簡潔、易懂的Rxjava入門教程 涵蓋 基本介紹、

手把手入門Keras

不同於其他深度學習框架,Keras,是基於 Python 的深度學習庫。它充當神經網路的高階 API 規範,既可作為使用者介面,也可擴充套件它在其中執行的其他深度學習框架後端的功能。起初,Keras是作為Theano 框架的簡化前端。之後,Keras API 成為了 Goog

手把手入門numpy,從此資料處理不再慌【四】

本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天是numpy專題的第四篇文章,numpy中的陣列重塑與三元表示式。 首先我們來看陣列重塑,所謂的重塑本質上就是改變陣列的shape。在保證陣列當中所有元素不變的前提下,變更陣列形狀的操作。比如常用的操作主要有兩個,一個是轉置,另外一

一分鐘瞭解下Spring Security

一、什麼是Spring Security? Spring Security是一個功能強大且高度可定製的身份驗證和訪問控制框架,它是用於保護基於Spring的應用程式的實際標準。 Spring Security是一個框架,致力於為Java應用程式提供身份驗證和授權。與所有Spring專案一樣,Spring Se

手把手入門MySQL零基礎入門教程

手把手教你入門MySQL零基礎入門教程! 目前MySQL已經成為最為流行的開源關系數據庫系統,並且一步一步地占領了原有商業數據庫的市場。可以看到Google、Facebook、Yahoo、網易、久遊等大公司都在使用MySQL數據庫,甚至將其作為核心應用的數據庫系統。而My

手把手抓取智聯招聘的“資料分析師”崗位

前言 很多網友在後臺跟我留言,是否可以分享一些爬蟲相關的文章,我便提供了我以前寫過的爬蟲文章的連結(如下連結所示),大家如果感興趣的話也可以去看一看哦。在本文中,我將以智聯招聘為例,分享一下如何抓取近5000條的資料分析崗資訊。 往期爬蟲連結 上海歷史天氣和空氣質量資料獲取(Pyth

小白福利Python基礎語法入門

這是一篇正經的乾貨分享!帶領小白入門Python。 我們學習之前可以先來了解一下Python~ Python的特點 1. 簡單 Python是一種代表簡單思想的語言。 2. 易學 Python有極其簡單的語法。 3. 免費、開源 P

12個最佳的響應式網頁設計教程,輕鬆入門

如何讓你的網站在其出現的任何裝置和螢幕尺寸上能夠完美的呈現?響應式設計完美的解決了這一難題,作為現在的網頁設計師都應該瞭解響應式網頁設計的原則。而對於剛步入網頁設計的新手設計師,如果你還不瞭解什麼是響應式設計?如何製作響應式頁面?這篇文章為大家提供了12個基礎的響應式網頁設計的教程,結尾還附上了個人

區塊鏈能養貓養狗了?手把手復現AI+區塊鏈寫碼全過程(附程式碼)

區塊鏈養貓養狗、區塊鏈遊戲、區塊鏈遊戲,區塊鏈旅遊……打著區塊鏈名頭的專案蜂擁上線。 如何將區塊鏈和AI兩種不同技術結合?如何在python中編寫工作證明演算法?一致性演算法有哪些? 雷鋒字幕組特別編譯了本期「區塊鏈一致性演算法和人工

現場玩轉兒IoT資料?百度雲手把手

話說,如今發展勢頭火熱的物聯網,其資料究竟有何special? 每分鐘數百萬條事件,還有大量間歇資料流? 時序資料是常態,還有可能出現“易逝”現象? 各種資料來源產生,從“感測器讀數”到“現場視訊流”簡直應有盡有? 好吧!如此看來,再加上日漸增長的互聯裝置,爆炸式擴容

一個炫字都不夠??手把手打造3D自定義view

分享一則最近流行的笑話: 最新科學研究表明:寒冷可以使人保持年輕,樓下的王大爺表示雖然今年已經60多歲了,但是仍然冷的跟孫子一樣。 呃。好吧,這個冬天確實有點冷,在廣州活生生的把我這個原生北方人,凍成一條狗。(研究表明:寒冷可以讓人類基因突變。。。。)

蟲師入門Chrome Headless,從此爬蟲0門檻

爬蟲終結者 Chrome Headless 簡介 自從Google官方釋出了Chrome瀏覽器的無形態模式之後,PhantomJS 維護者 Vitaly Slobodin 隨即在郵件

40 篇原創乾貨,進入 Spring Boot 殿堂

兩個月前,鬆哥總結過一次已經完成的 Spring Boot 教程,當時感受到了小夥伴們巨大的熱情。 兩個月過去了,鬆哥的 Spring Boot 教程又更新了不少,為了方便小夥伴們查詢,這裡再給大家做一個索引參考。 需要再次說明的是,這一系列教程不是終點,而是一個起點,鬆哥後期還會不斷完善這個教程,也會持續更

核心業務“瘦身”進行時手把手搭建海量資料實時處理架構

01 背景線上交易服務平臺目的是減輕核心繫統計算壓力和核心效能負荷壓力,通過該平臺可以將核心系統的交易資料實時捕獲、實時計算加工、計算結果保存於SequoiaDB中。並能實時的為使用者提供線上交易查詢服務。線上交易服務平臺基於實時處理架構設計,通過將核心系統的資料變更,實時的同步到在平臺數據庫,從而達到資料實

手把手實戰下Spring的七種事務傳播行為

目錄 一、什麼是事務傳播行為? 二、事務的7種傳播行為 三、7種傳播行為實戰 本文介紹Spring的七種事務傳播行為並通過程式碼演示下。 一、什麼是事務傳播行為? 事務傳播行為(propag

從零開始入門 K8s | 手把手理解 etcd

作者 | 曾凡鬆(逐靈) 阿里雲容器平臺高階技術專家 本文整理自《CNCF x Alibaba 雲原生技術公開課》第 16 講。 導讀:etcd 是用於共享配置和服務發現的分散式、一致性的 KV 儲存系統。本文從 etcd 專案發展所經歷的幾個重要時刻開始,為大家介紹了 etc

萬字長文入門Zookeeper

導讀 文章首發於微信公眾號【碼猿技術專欄】,原創不易,謝謝支援。 Zookeeper 相信大家都聽說過,最典型的使用就是作為服務註冊中心。今天陳某帶大家從零基礎入門 Zookeeper,看了本文,你將會對 Zookeeper 有了初步的瞭解和認識。 注意:本文基於 Zookeeper 的版本是 3.4.14

Pytorch入門——手把手配置雲伺服器環境

本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天這篇是Pytorch專題第一篇文章。 大家好,由於我最近自己在學習Pytorch框架的運用,並且也是為了響應許多讀者的需求,推出了這個Pytorch專題。由於這個專題是週末加更的,所以不能保證更新進度,我儘量和其他專題一樣,每週一