欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot淺析安全管理之OAuth2框架

 更新時間:2022年08月12日 14:04:04   作者:一只小熊貓呀  
安全管理是軟件系統(tǒng)必不可少的的功能。根據(jù)經(jīng)典的“墨菲定律”——凡是可能,總會發(fā)生。如果系統(tǒng)存在安全隱患,最終必然會出現(xiàn)問題,這篇文章主要介紹了SpringBoot安全管理OAuth2框架的使用

OAuth2簡介

OAuth 是一個開放標(biāo)準(zhǔn),該標(biāo)準(zhǔn)允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲的私密資源(如頭像、照片、視頻等),而在這個過程中無須將用戶名和密碼提供給第三方應(yīng)用。

實現(xiàn)這一功能是通過一個令牌(token),而不是用戶名和密碼來訪問他們存放在特定服務(wù)提供者的數(shù)據(jù)。每一個令牌授權(quán)一個特定的網(wǎng)站在特定的時間段內(nèi)訪問特定的資源。

這樣 OAuth 讓用戶可以授權(quán)第三方網(wǎng)站靈活的訪問存儲在另一些資源服務(wù)器的特定信息,而非所有內(nèi)容。例如,用戶想通過 QQ 登錄知乎,這時知乎就是一個第三方應(yīng)用,知乎要訪問用戶的一些基本信息就需要得到用戶的授權(quán),如果用戶把自己的 QQ 用戶名和密碼告訴知乎,那么知乎就能訪問用戶的所有數(shù)據(jù),并且只有用戶修改密碼才能收回權(quán)限,這種授權(quán)方式安全隱患很大,如果使用 OAuth ,就能很好的解決這一問題。

采用令牌的方式可以讓用戶靈活的對第三方應(yīng)用授權(quán)或者收回權(quán)限。OAuth 2 是 OAuth 協(xié)議的下一版本,但不向下兼容 OAuth 1.0 。

OAuth 2 關(guān)注客戶端開發(fā)者的簡易型,同時為Web應(yīng)用、桌面應(yīng)用,移動設(shè)備、起居室設(shè)備提供專門的認(rèn)證流程。傳統(tǒng)的 Web 開發(fā)登錄認(rèn)證一般都是基于 Session 的,但是前后端分離的架構(gòu)中繼續(xù)使用 Session 會有許多不便,因為移動端(Android、IOS、微信小程序等)要么不支持 Cookie(微信小程序),要么使用非常不便,對于這些問題,使用 OAuth 2 認(rèn)證都能解決。

OAuth2角色

先了解 OAuth 2 中幾個基本的角色

  • 資源所有者:即用戶,具有頭像、照片、視頻等資源
  • 客戶端:即第三方應(yīng)用
  • 授權(quán)服務(wù)器:用來驗證用戶提供的信息是否正確,并返回一個令牌給第三方應(yīng)用
  • 資源服務(wù)器:提供給用戶資源的服務(wù)器,例如頭像、照片、視頻等資源

一般來說,授權(quán)服務(wù)器和資源服務(wù)器可以是同一臺服務(wù)器。

OAuth2授權(quán)流程

步驟01:客戶端(第三方應(yīng)用)向用戶請求授權(quán)。

步驟02:用戶單擊客戶端所呈現(xiàn)的服務(wù)授權(quán)頁面上的同意授權(quán)按鈕后,服務(wù)端返回一個授權(quán)許可憑證給客戶端。

步驟03:客戶端拿著授權(quán)許可證去授權(quán)服務(wù)器申請令牌。

步驟04:授權(quán)服務(wù)器驗證信息無誤后,發(fā)放令牌給客戶端。

步驟05:客戶端拿著令牌去資源服務(wù)器訪問資源。

步驟06:資源服務(wù)器驗證令牌無誤后開放資源。

授權(quán)模式

OAuth 協(xié)議的授權(quán)模式共分為 4 種,如下

  • 授權(quán)碼模式:授權(quán)碼(authorization code)是功能最完整、流程最嚴(yán)謹(jǐn)?shù)氖跈?quán)模式。它的特點就是通過客戶端的服務(wù)器與授權(quán)服務(wù)器進(jìn)行交互,國內(nèi)常見的第三方平臺登錄功能基本都是使用這種模式
  • 簡化模式:簡化模式不需要客戶端服務(wù)器參與,直接在瀏覽器中向授權(quán)服務(wù)器申請令牌,一般若是純靜態(tài)頁面,則可以采用這種方式
  • 密碼模式:用戶把用戶名密碼直接告訴客戶端,客戶端使用這些信息向授權(quán)服務(wù)器申請令牌。這需要用戶對客戶端高度信息,例如客戶端應(yīng)用和服務(wù)提供商是同一家公司
  • 客戶端模式:客戶端使用自己的名義而不是用戶的名義想服務(wù)提供者申請授權(quán)。嚴(yán)格來說,客戶端模式并不能算作 OAuth 協(xié)議要解決的問題的一種解決方案,但是,對于開發(fā)者而言,在一些前后端分離應(yīng)用或者為移動端提供的認(rèn)證授權(quán)服務(wù)器上使用這種模式還是非常方便的

4 種模式各有千秋,分別適用于不同的開發(fā)場景,開發(fā)者根據(jù)實際情況進(jìn)行選擇

實踐

此處介紹的是在前后端分離應(yīng)用(或為移動端、微信小程序等)提供的認(rèn)證服務(wù)器中如何搭建 OAuth 服務(wù),因此主要介紹密碼模式。

1. 創(chuàng)建項目添加依賴

創(chuàng)建 Spring Boot Web 項目,添加如下依賴

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
  <exclusions>
    <exclusion>
      <groupId>io.lettuce</groupId>
      <artifactId>lettuce-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.security.oauth</groupId>
  <artifactId>spring-security-oauth2</artifactId>
  <version>2.3.3.RELEASE</version>
</dependency>

由于 Spring Boot 中的 OAuth 協(xié)議是在 Spring Security 的基礎(chǔ)上完成的,因此首先要添加 Spring Security 依賴,要用到 OAuth 2,因此添加 OAuth 2 相關(guān)依賴,令牌可以存儲在 Redis 緩存服務(wù)器上,同時 Redis 具有過期等功能,很適合令牌的存儲,因此也加入 Redis 依賴。

配置 application.properties

spring.redis.database=0
spring.redis.host=ip地址
spring.redis.port=6379
spring.redis.password=root
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.min-idle=0

2. 配置授權(quán)服務(wù)器

授權(quán)服務(wù)器和資源服務(wù)器可以是同一臺服務(wù)器,也可以是不同服務(wù)器,此處假設(shè)是同一臺服務(wù)器,通過不同的配置分別開啟授權(quán)服務(wù)器和資源服務(wù)器,首先是授權(quán)服務(wù)器:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    RedisConnectionFactory redisConnectionFactory;
    @Autowired
    UserDetailsService userDetailsService;
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("password")
                .authorizedGrantTypes("password", "refresh_token")
                .accessTokenValiditySeconds(1800)
                .resourceIds("rid")
                .scopes("all")
                .secret("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq");
    }
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory))
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
    }
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients();
    }
}

代碼解釋:

  • 自定義類繼承自 AuthorizationServerConfigurerAdapter ,完成對授權(quán)服務(wù)器的配置,然后通過 @EnableAuthorizationServer 注解開啟授權(quán)服務(wù)器
  • 注入 AuthenticationManager 用來支持 password 模式
  • 注入 RedisConnectionFactory 用來完成 Redis 緩存,將令牌信息儲存到 Redis 緩存中
  • 注入 UserDetailsService 該對象為刷新 token 提供支持
  • 在 configure(ClientDetailsServiceConfigurer clients) 方法中配置 password 授權(quán)模式,authorizedGrantTypes 表示 OAuth 2 中的授權(quán)模式為 password 和 refresh_token 兩種,在標(biāo)準(zhǔn)的 OAuth 2 協(xié)議中,授權(quán)模式并不包括 refresh_token ,但是在 Spring Security 的實現(xiàn)中將其歸為一種,因此如果要實現(xiàn) access_token 的刷新,就需要添加這樣一種授權(quán)模式;accessTokenValiditySeconds 方法配置了 access_token 的過期時間;resourceIds 配置了資源 id;secret 方法配置了加密后的密碼,明文是 123
  • configure(AuthorizationServerEndpointsConfigurer endpoints) 方法配置了令牌的存儲,AuthenticationManager 和 UserDetailsService 主要用于支持 password 模式以及令牌的刷新
  • configure(AuthorizationServerSecurityConfigurer security) 方法配置表示支持 client_id 和 client_secret 做登錄認(rèn)證

3. 配置資源服務(wù)器

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("rid").stateless(true);
    }
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/user/**").hasRole("user")
                .anyRequest().authenticated();
    }
}

代碼解釋:

  • 自定義類繼承自 ResourceServerConfigurerAdapter ,并添加 @EnableResourceServer 注解開啟資源服務(wù)器配置
  • resources.resourceId(“rid”).stateless(true); 配置資源 id,這里的資源 id 和授權(quán)服務(wù)器中的資源 id 一直,然后設(shè)置這些資源僅基于令牌認(rèn)證
  • configure(HttpSecurity http) 方法配置 HttpSecurity

4. 配置 Security

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        return super.userDetailsService();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq")
                .roles("admin")
                .and()
                .withUser("sang")
                .password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq")
                .roles("user");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/oauth/**").authorizeRequests()
                .antMatchers("/oauth/**").permitAll()
                .and().csrf().disable();
    }
}

這里兩個 Bean 將注入授權(quán)服務(wù)器配置類中使用,另外,這里的 HttpSecurity 配置主要是配置 /oauth/** 模式的 URL ,這一類的請求直接放行。在 Spring Security 配置和資源服務(wù)器配置中,一共涉及兩個 HttpSecurity ,其中 Spring Security 中的配置優(yōu)先級高于資源服務(wù)器中的配置,即請求地址先經(jīng)過 Spring Security 的 HttpSecurity ,再經(jīng)過資源服務(wù)器的 HttpSecurity。

5. 驗證測試

首先創(chuàng)建三個簡單的請求地址

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

根據(jù)前文的配置,要請求這三個地址,分別需要 admin 角色、user 角色以及登錄后訪問。

所有都配置完成后,啟動 Redis 服務(wù)器,再啟動 Spring Boot 項目,首先發(fā)送一個 POST 請求獲取 token,請求地址如下(注意這里是一個 POST 請求,為了顯示方便,將參數(shù)寫在地址欄中):http://localhost:8080/oauth/token?username=sang&password=123&grant_type=password&client_id=password&scope=all&client_secret=123

請求地址中包含的參數(shù)有用戶名、密碼、授權(quán)模式、客戶端 id 、scope 以及客戶端密碼,基本就是授權(quán)服務(wù)器中所配置的數(shù)據(jù),請求結(jié)果如圖

其中 access_token 是獲取其它資源時要用的令牌,refresh_token 用來刷新令牌,expires_in 表示 access_token 過期時間,當(dāng) access_token 過期后,使用 refresh_token 重新獲取新的 access_token (前提是 refresh_token 未過期),請求地址(注意也是POST請求):http://localhost:8080/oauth/token?grant_type=refresh_token&refresh_token=693b0e36-4515-442a-8c5d-90bade3c74d2&client_id=password&client_secret=123

獲取新的 access_token 時需要攜帶上 refresh_token ,同事授權(quán)模式設(shè)置為 refresh_token ,在獲取的結(jié)果中 access_token 會變化,同時 access_token 有效期也會變化,如圖

接下來訪問所有資源,攜帶上 access_token 參數(shù)即可,例如 /user/hello 接口:http://localhost:8080/user/hello?access_token=0497e4bc-df37-460e-8755-b813b9dbf36a,訪問結(jié)果如圖

如果非法訪問一個資源,例如 sang 用戶訪問 /admin/hello 接口,結(jié)果如圖

到此,一個 password 模式的 OAuth 認(rèn)證體系就搭建成功了。

OAuth 中的認(rèn)證模式有 4 中,開發(fā)者需要結(jié)合自己開發(fā)的實際情況選擇其中一種,此處介紹的是在前后端分離應(yīng)用中常用的 password 模式,其它的授權(quán)模式也都有自己的使用場景。

整體來講,Spring Security OAuth 2 的使用還是較復(fù)雜的,配置也比較繁瑣,如果開發(fā)者的應(yīng)用場景比較簡單,完全可以按照此處介紹的授權(quán)流程自己搭建 OAuth 2 認(rèn)證體系。

到此這篇關(guān)于SpringBoot淺析安全管理之OAuth2框架的文章就介紹到這了,更多相關(guān)SpringBoot OAuth2框架內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java使用JSONObject實例

    java使用JSONObject實例

    JAVA中JSONObject對象的使用方法
    2013-11-11
  • java結(jié)合email實現(xiàn)自動推送功能

    java結(jié)合email實現(xiàn)自動推送功能

    這篇文章主要介紹了java結(jié)合email實現(xiàn)自動推送功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • SpringBoot實現(xiàn)Md5對數(shù)據(jù)庫數(shù)據(jù)加密的示例

    SpringBoot實現(xiàn)Md5對數(shù)據(jù)庫數(shù)據(jù)加密的示例

    本文主要介紹了SpringBoot實現(xiàn)Md5對數(shù)據(jù)庫數(shù)據(jù)加密的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java快速入門掌握類與對象及變量的使用

    Java快速入門掌握類與對象及變量的使用

    類和對象是兩種以計算機(jī)為載體的計算機(jī)語言的合稱。對象是對客觀事物的抽象,類是對對象的抽象。類是一種抽象的數(shù)據(jù)類型;變量就是可以變化的量,存儲在內(nèi)存中—個可以擁有在某個范圍內(nèi)的可變存儲區(qū)域
    2022-04-04
  • SpringBoot java-jar命令行啟動原理解析

    SpringBoot java-jar命令行啟動原理解析

    這篇文章主要介紹了SpringBoot java-jar命令行啟動原理解析,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java中char數(shù)組(字符數(shù)組)與字符串String類型的轉(zhuǎn)換方法

    Java中char數(shù)組(字符數(shù)組)與字符串String類型的轉(zhuǎn)換方法

    這篇文章主要介紹了Java中char數(shù)組(字符數(shù)組)與字符串String類型的轉(zhuǎn)換方法,涉及Java中toCharArray與valueOf方法的使用技巧,需要的朋友可以參考下
    2015-12-12
  • Java中隨機(jī)數(shù)的產(chǎn)生方式與原理詳解

    Java中隨機(jī)數(shù)的產(chǎn)生方式與原理詳解

    這篇文章主要介紹了Java中隨機(jī)數(shù)的產(chǎn)生方式與原理詳解的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • 一篇文章帶你了解Java之關(guān)鍵字和保留字

    一篇文章帶你了解Java之關(guān)鍵字和保留字

    Java 保留字列表 (依字母排序 共14組) : Java保留字是指現(xiàn)有Java版本尚未使用 但以后版本可能會作為關(guān)鍵字使用,希望本篇文章能給您帶來幫助
    2021-08-08
  • Java中設(shè)置JAVA_HOME無效的解決方法

    Java中設(shè)置JAVA_HOME無效的解決方法

    最近遇到一個問題,就是配置JAVA_HOME無效,不管怎么改,運行Java -version始終是最初的那個java版本,所以這篇文章主要給大家介紹了關(guān)于Java中設(shè)置JAVA_HOME無效的解決方法,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-09-09
  • springboot2.5.0和redis整合配置詳解

    springboot2.5.0和redis整合配置詳解

    本篇文章向大家介紹springboot2.5.0 整合 redis 配置方法,教大家在pom添加依賴的方法如何調(diào)用redis,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-06-06

最新評論