国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

OAuth2.0從入門到實戰(zhàn)(附github地址)

這篇具有很好參考價值的文章主要介紹了OAuth2.0從入門到實戰(zhàn)(附github地址)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

OAuth2.0

OAuth2.0的含義與思想

OAuth 是一個開放標(biāo)準(zhǔn),該標(biāo)準(zhǔn)允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲的私密資源(如頭像、照片、視頻等),而在這個過程中無需將用戶名和密碼提供給第三方應(yīng)用。實現(xiàn)這一功能是通過提供一個令牌(token),而不是用戶名和密碼來訪問他們存放在特定服務(wù)提供者的數(shù)據(jù)。采用令牌(token)的方式可以讓用戶靈活的對第三方應(yīng)用授權(quán)或者收回權(quán)限。

OAuth2 是 OAuth 協(xié)議的下一版本,但不向下兼容 OAuth 1.0。傳統(tǒng)的 Web 開發(fā)登錄認(rèn)證一般都是基于 session 的,但是在前后端分離的架構(gòu)中繼續(xù)使用 session 就會有許多不便,因為移動端(Android、iOS、微信小程序等)要么不支持 cookie(微信小程序),要么使用非常不便,對于這些問題,使用 OAuth2 認(rèn)證都能解決。

對于大家而言,我們在互聯(lián)網(wǎng)應(yīng)用中最常見的 OAuth2 應(yīng)該就是各種第三方登錄了,例如 QQ 授權(quán)登錄、微信授權(quán)登錄、微博授權(quán)登錄、GitHub 授權(quán)登錄等等。

[快遞員的例子](OAuth 2.0 的一個簡單解釋 - 阮一峰的網(wǎng)絡(luò)日志 (ruanyifeng.com))

我住在一個大型的居民小區(qū)。

OAuth2.0從入門到實戰(zhàn)(附github地址)

小區(qū)有門禁系統(tǒng)。

OAuth2.0從入門到實戰(zhàn)(附github地址)

進(jìn)入的時候需要輸入密碼。

OAuth2.0從入門到實戰(zhàn)(附github地址)

我經(jīng)常網(wǎng)購和外賣,每天都有快遞員來送貨。我必須找到一個辦法,讓快遞員通過門禁系統(tǒng),進(jìn)入小區(qū)。

OAuth2.0從入門到實戰(zhàn)(附github地址)

如果我把自己的密碼,告訴快遞員,他就擁有了與我同樣的權(quán)限,這樣好像不太合適。萬一我想取消他進(jìn)入小區(qū)的權(quán)力,也很麻煩,我自己的密碼也得跟著改了,還得通知其他的快遞員。

有沒有一種辦法,讓快遞員能夠自由進(jìn)入小區(qū),又不必知道小區(qū)居民的密碼,而且他的唯一權(quán)限就是送貨,其他需要密碼的場合,他都沒有權(quán)限?

于是,我設(shè)計了一套授權(quán)機(jī)制:

OAuth2.0從入門到實戰(zhàn)(附github地址)

  • 第一步,門禁系統(tǒng)的密碼輸入器下面,增加一個按鈕,叫做**“獲取授權(quán)”**??爝f員需要首先按這個按鈕,去申請授權(quán)。
  • 第二步,他按下按鈕以后,屋主(也就是我)的手機(jī)就會跳出對話框:有人正在要求授權(quán)。系統(tǒng)還會顯示該快遞員的姓名、工號和所屬的快遞公司。
  • 我確認(rèn)請求屬實,就點擊按鈕,告訴門禁系統(tǒng),我同意給予他進(jìn)入小區(qū)的授權(quán)。
  • 第三步,門禁系統(tǒng)得到我的確認(rèn)以后,向快遞員顯示一個進(jìn)入小區(qū)的令牌(access token)。令牌就是類似密碼的一串?dāng)?shù)字,只在短期內(nèi)(比如七天)有效。
  • 第四步,快遞員向門禁系統(tǒng)輸入令牌,進(jìn)入小區(qū)。

有人可能會問,為什么不是遠(yuǎn)程為快遞員開門,而要為他單獨生成一個令牌?這是因為快遞員可能每天都會來送貨,第二天他還可以復(fù)用這個令牌。另外,有的小區(qū)有多重門禁,快遞員可以使用同一個令牌通過它們。

互聯(lián)網(wǎng)的例子

例如我們有一個“云打印”的網(wǎng)站,可以將用戶存儲在Google的照片,打印出來。用戶為了使用該服務(wù),需要讓“云打印”這個網(wǎng)站訪問自己存儲在Google的照片。

? 如何獲得用戶的授權(quán)呢?

傳統(tǒng)方案是將用戶將自己的Google賬號密碼告訴“云打印”網(wǎng)站。但是這種方案會有很多缺點:

  • 云打印存儲Google密碼,不安全
  • Google必須有密碼登錄的功能
  • 云打印擁有了獲取用戶Google資源的權(quán)力,但是用戶無法限制云打印獲得授權(quán)的范圍和有效期
  • 用戶只有修改密碼,才可以收回賦予的權(quán)利,但是這樣嚴(yán)重影響其它應(yīng)用
  • 只要有一個第三方應(yīng)用被破解,密碼就會泄漏

OAuth就是為了解決上面這些問題而誕生的。

用OAuth的方案:云打印請求獲取授權(quán),用戶同意給云打印授權(quán),云打印使用上一步的授權(quán)碼向Google的認(rèn)證服務(wù)器申請令牌,然后云打印使用令牌向Google的資源服務(wù)器申請資源,Google的資源服務(wù)器確認(rèn)令牌并開放資源。

簡單說,OAuth 就是一種授權(quán)機(jī)制。數(shù)據(jù)的所有者告訴系統(tǒng),同意授權(quán)第三方應(yīng)用進(jìn)入系統(tǒng),獲取這些數(shù)據(jù)。系統(tǒng)從而產(chǎn)生一個短期的進(jìn)入令牌(token),用來代替密碼,供第三方應(yīng)用使用。

令牌與密碼

令牌(token)與密碼(password)的作用是一樣的,都可以進(jìn)入系統(tǒng),但是有三點差異。

  1. 令牌是短期的,到期會自動失效,用戶自己無法修改。密碼一般長期有效,用戶不修改,就不會發(fā)生變化。
  2. 令牌可以被數(shù)據(jù)所有者撤銷,會立即失效。以上例而言,屋主可以隨時取消快遞員的令牌。密碼一般不允許被他人撤銷。
  3. 令牌有權(quán)限范圍(scope),比如只能進(jìn)小區(qū)的二號門。對于網(wǎng)絡(luò)服務(wù)來說,只讀令牌就比讀寫令牌更安全。密碼一般是完整權(quán)限。

上面這些設(shè)計,保證了令牌既可以讓第三方應(yīng)用獲得權(quán)限,同時又隨時可控,不會危及系統(tǒng)安全。這就是 OAuth 2.0 的優(yōu)點。

OAuth2.0的四種授權(quán)方式

用戶如何給與第三方應(yīng)用權(quán)限,從而第三方可以根據(jù)此授權(quán)獲取令牌?

RFC 6749

OAuth 2.0 的標(biāo)準(zhǔn)是 RFC 6749 文件。該文件先解釋了 OAuth 是什么。

OAuth 引入了一個授權(quán)層,用來分離兩種不同的角色:客戶端和資源所有者?!Y源所有者同意以后,資源服務(wù)器可以向客戶端頒發(fā)令牌??蛻舳送ㄟ^令牌,去請求數(shù)據(jù)。

這段話的意思就是,**OAuth 的核心就是向第三方應(yīng)用頒發(fā)令牌。**然后,RFC 6749 接著寫道:

(由于互聯(lián)網(wǎng)有多種場景,)本標(biāo)準(zhǔn)定義了獲得令牌的四種授權(quán)方式(authorization grant )。

也就是說,**OAuth 2.0 規(guī)定了四種獲得令牌的流程。你可以選擇最適合自己的那一種,向第三方應(yīng)用頒發(fā)令牌。**下面就是這四種授權(quán)方式。

  • 授權(quán)碼(authorization-code)
  • 隱藏式(implicit)
  • 密碼式(password):
  • 客戶端憑證(client credentials)

注意,不管哪一種授權(quán)方式,第三方應(yīng)用申請令牌之前,都必須先到系統(tǒng)備案,說明自己的身份,然后會拿到兩個身份識別碼:客戶端 ID(client ID)和客戶端密鑰(client secret)。這是為了防止令牌被濫用,沒有備案過的第三方應(yīng)用,是不會拿到令牌的。

一、授權(quán)碼(前后端分離)

授權(quán)碼(authorization code)方式,指的是第三方應(yīng)用先申請一個授權(quán)碼,然后再用該碼獲取令牌。

這種方式是最常用的流程,安全性也最高,它適用于那些有后端的 Web 應(yīng)用。授權(quán)碼通過前端傳送,令牌則是儲存在后端,而且所有與資源服務(wù)器的通信都在后端完成。這樣的前后端分離,可以避免令牌泄漏。

A網(wǎng)站要獲取B網(wǎng)站的授權(quán)

1?? 第一步,A 網(wǎng)站(云打印)提供一個鏈接,用戶點擊后就會跳轉(zhuǎn)到 B (Google)網(wǎng)站,授權(quán)用戶數(shù)據(jù)給 A 網(wǎng)站使用。下面就是 A 網(wǎng)站跳轉(zhuǎn) B 網(wǎng)站的一個示意鏈接。

https://b.com/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

上面 URL 中,response_type參數(shù)表示要求返回授權(quán)碼(code),client_id參數(shù)讓 B 知道是誰在請求,redirect_uri參數(shù)是 B 接受或拒絕請求后的跳轉(zhuǎn)網(wǎng)址,scope參數(shù)表示要求的授權(quán)范圍(這里是只讀)。

2?? 第二步,用戶跳轉(zhuǎn)后,B 網(wǎng)站會要求用戶登錄,然后詢問是否同意給予 A 網(wǎng)站授權(quán)。用戶表示同意,這時 B 網(wǎng)站就會跳回redirect_uri參數(shù)指定的網(wǎng)址。跳轉(zhuǎn)時,會傳回一個授權(quán)碼,就像下面這樣。

https://a.com/callback?code=AUTHORIZATION_CODE

OAuth2.0從入門到實戰(zhàn)(附github地址)

3?? 第三步,A 網(wǎng)站拿到授權(quán)碼以后,就可以在后端,向 B 網(wǎng)站請求令牌。

https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL

上面 URL 中,client_id參數(shù)和client_secret參數(shù)用來讓 B 確認(rèn) A 的身份(client_secret參數(shù)是保密的,因此只能在后端發(fā)請求),grant_type參數(shù)的值是AUTHORIZATION_CODE,表示采用的授權(quán)方式是授權(quán)碼,code參數(shù)是上一步拿到的授權(quán)碼,redirect_uri參數(shù)是令牌頒發(fā)后的回調(diào)網(wǎng)址。

OAuth2.0從入門到實戰(zhàn)(附github地址)

4?? 第四步,B 網(wǎng)站收到請求以后,就會頒發(fā)令牌。具體做法是向redirect_uri指定的網(wǎng)址,發(fā)送一段 JSON 數(shù)據(jù)。

{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{...}
}

上面 JSON 數(shù)據(jù)中,access_token字段就是令牌,A 網(wǎng)站在后端拿到了。

OAuth2.0從入門到實戰(zhàn)(附github地址)

最后A網(wǎng)站就可以通過令牌來訪問B網(wǎng)站的資源了。

二、隱藏式(純前端應(yīng)用)

有些 Web 應(yīng)用是純前端應(yīng)用,沒有后端。這時就不能用上面的方式了,必須將令牌儲存在前端。RFC 6749 就規(guī)定了第二種方式,允許直接向前端頒發(fā)令牌。這種方式?jīng)]有授權(quán)碼這個中間步驟,所以稱為(授權(quán)碼)“隱藏式”(implicit)。

1?? 第一步,A 網(wǎng)站提供一個鏈接,要求用戶跳轉(zhuǎn)到 B 網(wǎng)站,授權(quán)用戶數(shù)據(jù)給 A 網(wǎng)站使用。

https://b.com/oauth/authorize?
  response_type=token&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

上面 URL 中,response_type參數(shù)為token,表示要求直接返回令牌。

2?? 第二步,用戶跳轉(zhuǎn)到 B 網(wǎng)站,登錄后同意給予 A 網(wǎng)站授權(quán)。這時,B 網(wǎng)站就會跳回redirect_uri參數(shù)指定的跳轉(zhuǎn)網(wǎng)址,并且把令牌作為 URL 參數(shù),傳給 A 網(wǎng)站。

https://a.com/callback#token=ACCESS_TOKEN

上面 URL 中,token參數(shù)就是令牌,A 網(wǎng)站因此直接在前端拿到令牌。

OAuth2.0從入門到實戰(zhàn)(附github地址)

這種方式把令牌直接傳給前端,是很不安全的。因此,只能用于一些安全要求不高的場景,并且令牌的有效期必須非常短,通常就是會話期間(session)有效,瀏覽器關(guān)掉,令牌就失效了。

三、密碼式

如果你高度信任某個應(yīng)用,RFC 6749 也允許用戶把用戶名和密碼,直接告訴該應(yīng)用。該應(yīng)用就使用你的密碼,申請令牌,這種方式稱為"密碼式"(password)。

第一步,A 網(wǎng)站要求用戶提供 B 網(wǎng)站的用戶名和密碼。拿到以后,A 就直接向 B 請求令牌。

https://oauth.b.com/token?
  grant_type=password&
  username=USERNAME&
  password=PASSWORD&
  client_id=CLIENT_ID

上面 URL 中,grant_type參數(shù)是授權(quán)方式,這里的password表示"密碼式",usernamepassword是 B 的用戶名和密碼。

第二步,B 網(wǎng)站驗證身份通過后,直接給出令牌。注意,這時不需要跳轉(zhuǎn),而是把令牌放在 JSON 數(shù)據(jù)里面,作為 HTTP 回應(yīng),A 因此拿到令牌。

這種方式需要用戶給出自己的用戶名/密碼,顯然風(fēng)險很大,因此只適用于其他授權(quán)方式都無法采用的情況,而且必須是用戶高度信任的應(yīng)用。

四、憑證式(命令行應(yīng)用)

最后一種方式是憑證式(client credentials),適用于沒有前端的命令行應(yīng)用,即在命令行下請求令牌。

第一步,A 應(yīng)用在命令行向 B 發(fā)出請求。

https://oauth.b.com/token?
  grant_type=client_credentials&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET

上面 URL 中,grant_type參數(shù)等于client_credentials表示采用憑證式,client_idclient_secret用來讓 B 確認(rèn) A 的身份。

第二步,B 網(wǎng)站驗證通過以后,直接返回令牌。

這種方式給出的令牌,是針對第三方應(yīng)用的,而不是針對用戶的,即有可能多個用戶共享同一個令牌。

令牌的使用

A 網(wǎng)站拿到令牌以后,就可以向 B 網(wǎng)站的 API 請求數(shù)據(jù)了。

此時,每個發(fā)到 API 的請求,都必須帶有令牌。具體做法是在請求的頭信息,加上一個Authorization字段,令牌就放在這個字段里面。

curl -H "Authorization: Bearer ACCESS_TOKEN" \
"https://api.b.com"

上面命令中,ACCESS_TOKEN就是拿到的令牌。

更新令牌

令牌的有效期到了,如果讓用戶重新走一遍上面的流程,再申請一個新的令牌,很可能體驗不好,而且也沒有必要。OAuth 2.0 允許用戶自動更新令牌。

具體方法是,B 網(wǎng)站頒發(fā)令牌的時候,一次性頒發(fā)兩個令牌,一個用于獲取數(shù)據(jù),另一個用于獲取新的令牌(refresh token 字段)。令牌到期前,用戶使用 refresh token 發(fā)一個請求,去更新令牌。

https://b.com/oauth/token?
  grant_type=refresh_token&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET&
  refresh_token=REFRESH_TOKEN

上面 URL 中,grant_type參數(shù)為refresh_token表示要求更新令牌,client_id參數(shù)和client_secret參數(shù)用于確認(rèn)身份,refresh_token參數(shù)就是用于更新令牌的令牌。

B 網(wǎng)站驗證通過以后,就會頒發(fā)新的令牌。

OAuth2.0 客戶端實例

需求描述

我們這里將會演示將我們的應(yīng)用作為一個OAuth2.0客戶端來集成Github登錄,并實現(xiàn)對Github資源的訪問。

環(huán)境準(zhǔn)備

1?? 在Github注冊一個應(yīng)用,生成 client-id , client-secret

OAuth2.0從入門到實戰(zhàn)(附github地址)

2?? SpringSecurity的集成,SpringSecurity 本身提供了 GOOGLE GITHUB FACEBOOK OKTAOAuth2.0 接入支持,具體源碼在枚舉類 CommonOAuth2Provider 中。

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

演示Demo

1??首先將Github的Client-Id等信息配置到y(tǒng)ml文件:

server:
  port: 8888
spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: XXXXXXXXXXXXXXX
            client-secret: XXXXXXXXXXXXXXXXXXXX

2?? 提供一個home頁面Controller

    @GetMapping(value = "/")
    public String index() {
        log.info(SecurityContextHolder.getContext().getAuthentication().toString());
        return "Welcome " + SecurityContextHolder.getContext().getAuthentication();
    }

3?? 訪問localhost:8888/login

OAuth2.0從入門到實戰(zhàn)(附github地址)

點擊通過Github登錄:

OAuth2.0從入門到實戰(zhàn)(附github地址)

我們授權(quán)登錄后,頁面會重定向到我們配置的home頁面:

OAuth2.0從入門到實戰(zhàn)(附github地址)

借助 SpringSecurityOAuth2.0 的支持,我們幾乎不用寫什么代碼就實現(xiàn)了 Github 登錄集成。下面再通過幾個例子來了解更多的細(xì)節(jié)。

查看Github在我們應(yīng)用中的注冊信息

    @GetMapping(value = "/user/reg")
    public String registration() {
        ClientRegistration githubRegistration = this.clientRegistrationRepository.findByRegistrationId("github");
        log.info(githubRegistration.toString());
        return githubRegistration.toString();
    }

訪問之后會返回 registration 信息,其中包含了 clientId , clientSecretauthorizationGrantType , redirectUri , scopes 等。

OAuth2.0從入門到實戰(zhàn)(附github地址)

查看獲取到的AccessToken

    @GetMapping(value = "/user/token")
    public OAuth2AccessToken accessToken(OAuth2AuthenticationToken authentication) {
        OAuth2AuthorizedClient authorizedClient = this.authorizedClientService.loadAuthorizedClient(
                authentication.getAuthorizedClientRegistrationId(), authentication.getName());
        OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
        return accessToken;
    }

請求接口我們可以獲取到對應(yīng)的token信息:

{
    "tokenValue":"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",
    "issuedAt":"2023-02-08T06:05:05.107Z",
    "expiresAt":"2023-02-08T06:05:06.107Z",
    "tokenType":{
        "value":"Bearer"
    },
    "scopes":[
        "read:user"
    ]
}

通過AccessToken請求Github API

定義抽象 API 綁定類,通過攔截器將獲取到的 AccessToken 設(shè)置到后續(xù)請求頭中,通過 RestTemplate 實現(xiàn)對 API 的請求:

資料: 用戶 - GitHub 文檔

1?? 封裝Api Binding 為RestTemplate綁定請求頭

/**
 * @Description: 綁定請求頭Authorization
 * @Author: Ze WANG
 **/
public abstract class ApiBinding {
    protected RestTemplate restTemplate;

    public ApiBinding(String accessToken) {
        this.restTemplate = new RestTemplate();
        if (accessToken != null) {
            this.restTemplate.getInterceptors().add(getBearerTokenInterceptor(accessToken));
        } else {
            this.restTemplate.getInterceptors().add(getNoTokenInterceptor());
        }
    }

    private ClientHttpRequestInterceptor getBearerTokenInterceptor(String accessToken) {
        return new ClientHttpRequestInterceptor() {
            @Override
            public ClientHttpResponse intercept(HttpRequest request, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {
                request.getHeaders().add("Authorization", "Bearer " + accessToken);
                return execution.execute(request, bytes);
            }
        };
    }

    private ClientHttpRequestInterceptor getNoTokenInterceptor() {
        return new ClientHttpRequestInterceptor() {
            @Override
            public ClientHttpResponse intercept(HttpRequest request, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {
                throw new IllegalStateException("Can't access the Github API without an access token");
            }
        };
    }
}
/**
 * @Description: Github請求
 * @Author: Ze WANG
 **/
public class Github extends ApiBinding {
    private static final String BASE_URL = "https://api.github.com";

    public Github(String accessToken) {
        super(accessToken);
    }
    public String getProfile() {
        return restTemplate.getForObject(BASE_URL + "/user", String.class);
    }
}

2?? 封裝獲取accessToken的過程

/**
 * @Description: 封裝獲取accessToken的過程
 * @Author: Ze WANG
 **/
@Configuration
@Slf4j
public class SocialConfig {
    @Bean
    @RequestScope
    public Github github(OAuth2AuthorizedClientService clientService) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String accessToken = null;
        if (authentication.getClass().isAssignableFrom(OAuth2AuthenticationToken.class)) {
            OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
            String clientRegistrationId = oauthToken.getAuthorizedClientRegistrationId();
            if (clientRegistrationId.equals("github")) {
                OAuth2AuthorizedClient client = clientService.loadAuthorizedClient(clientRegistrationId, oauthToken.getName());
                if (client != null) {
                    accessToken = client.getAccessToken().getTokenValue();
                }
                log.info(accessToken);
            }
        }
        return new Github(accessToken);
    }
}

3?? Controller

@GetMapping(value = "/user/info")
public String info() {
    String profile = github.getProfile();
    log.info(github.getProfile());
    return profile;
}

4?? 測試請求

OAuth2.0從入門到實戰(zhàn)(附github地址)

OAuth2.0 授權(quán)碼實例

上一章節(jié)我們僅僅是模擬了第三方應(yīng)用如何通過OAuth2.0來實現(xiàn)Github的授權(quán)登錄,這一章節(jié),我們能將通過一個完整的Demo來梳理OAuth2.0的授權(quán)碼模式。

在這個案例中,主要包括如下服務(wù):

  • 第三方應(yīng)用
  • 授權(quán)服務(wù)器
  • 資源服務(wù)器
  • 用戶
項目 端口 備注
auth-server 8081 授權(quán)服務(wù)器
user-server 8082 資源服務(wù)器
client-app 8083 第三方應(yīng)用

搭建授權(quán)服務(wù)器

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

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

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

1?? 首先配置SpringSecurity的基礎(chǔ)配置:這段配置的目的,實際上就是配置用戶。

/**
 * @Description: SpringSecurity的基本配置
 * @Author: Ze WANG
 **/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 創(chuàng)建兩個用戶綁定角色
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password(new BCryptPasswordEncoder().encode("123"))
                .roles("admin")
                .and()
                .withUser("wangze")
                .password(new BCryptPasswordEncoder().encode("123"))
                .roles("user");
    }

    /**
     * 配置表單登錄
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().formLogin();
    }
}

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

首先我們提供了一個 TokenStore 的實例,這個是指你生成的 Token 要往哪里存儲,我們可以存在 Redis 中,也可以存在內(nèi)存中,也可以結(jié)合 JWT 等等,這里,我們就先把它存在內(nèi)存中,所以提供一個 InMemoryTokenStore 的實例即可。

/**
 * @Description: Token存儲位置
 * @Author: Ze WANG
 **/
@Configuration
public class AccessTokenConfig {
    @Bean
    TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }
}
/**
 * @Description: 授權(quán)服務(wù)
 * @Author: Ze WANG
 **/
//@EnableAuthorizationServer 注解,表示開啟授權(quán)服務(wù)器的自動化配置。
@EnableAuthorizationServer
@Configuration
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
    @Autowired
    TokenStore tokenStore;
    @Autowired
    ClientDetailsService clientDetailsService;

    /**
     * 主要用來配置 Token 的一些基本信息,例如 Token 是否支持刷新、Token 的存儲位置、Token 的有效期以及刷新 Token 的有效期等等。
     */
    @Bean
    AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices services = new DefaultTokenServices();
        //設(shè)置客戶端詳細(xì)信息服務(wù)
        services.setClientDetailsService(clientDetailsService);
        //設(shè)置支持刷新令牌
        services.setSupportRefreshToken(true);
        //設(shè)置支持刷新令牌
        services.setTokenStore(tokenStore);
        //設(shè)置訪問令牌有效期秒數(shù)
        services.setAccessTokenValiditySeconds(60 * 60 * 2);
        //設(shè)置刷新令牌有效期秒數(shù)
        services.setRefreshTokenValiditySeconds(60 * 60 * 24 * 3);
        return services;
    }


    /**
     * 用來配置令牌端點的安全約束,也就是這個端點誰能訪問,誰不能訪問。
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("permitAll()")
                .allowFormAuthenticationForClients();
    }

    /**
     * 第三方應(yīng)用(客戶端)詳細(xì)信息服務(wù)配置,此處類似與github上注冊應(yīng)用
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("wz-app")
                .secret(new BCryptPasswordEncoder().encode("123"))
                .resourceIds("res1")
                .authorizedGrantTypes("authorization_code","refresh_token")
                .scopes("all")
                .redirectUris("http://localhost:8083/index.html");
    }

    /**
     * 用來配置令牌的訪問端點和令牌服務(wù)
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //authorizationCodeServices用來配置授權(quán)碼(Code)的存儲,這里我們是存在在內(nèi)存中
        endpoints.authorizationCodeServices(authorizationCodeServices())
                //tokenServices 用來配置令牌的存儲,即 access_token 的存儲位置,這里我們也先存儲在內(nèi)存中
                .tokenServices(tokenServices());
    }
    @Bean
    AuthorizationCodeServices authorizationCodeServices() {
        return new InMemoryAuthorizationCodeServices();
    }
}

搭建資源服務(wù)器

/**
 * @Description: 資源服務(wù)器配置
 * @Author: Ze WANG
 **/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    /**
     * RemoteTokenServices 中我們配置了 access_token 的校驗地址、client_id、client_secret 這三個信息,
     */
    @Bean
    RemoteTokenServices tokenServices() {
        RemoteTokenServices services = new RemoteTokenServices();
        //Spring Security 默認(rèn)校驗地址
        services.setCheckTokenEndpointUrl("http://localhost:8081/oauth/check_token");
        services.setClientId("wz-app");
        services.setClientSecret("123");
        return services;
    }

    /**
     * 當(dāng)用戶來資源服務(wù)器請求資源時,會攜帶上一個 access_token,通過這里的配置,就能夠校驗出 token 是否正確等。
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("res1").tokenServices(tokenServices());
    }

    /**
     * 配置一下資源的攔截規(guī)則,admin的資源需要有admin的權(quán)限
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .anyRequest().authenticated();
    }
}

資源

/**
 * @Description: 測試接口
 * @Author: Ze WANG
 **/
@RestController
public class ResController {

    @GetMapping("/res")
    public String hello() {
        return "====普通資源====";
    }
    @GetMapping("/admin/res")
    public String admin() {
        return "====admin資源====";
    }
}

第三方應(yīng)用搭建

為了簡單的演示,此處使用Thymeleaf來寫少量簡單的前端代碼:在resources/template目錄下,創(chuàng)建index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>wz-app</title>
</head>
<body>
<h1>Hello!  WZ-APP</h1>

<hr>
登錄:
<a href="http://localhost:8081/oauth/authorize?client_id=wz-app&response_type=code&scope=all&redirect_uri=http://localhost:8083/index.html">第三方登錄</a>
<br>
<h3 th:text="${token}"></h3>
<h1 th:text="${res}"></h1>


</body>
</html>

然后提供一個測試Controller:

@Controller
public class HelloController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/index.html")
    public String hello(String code, Model model) {
        if (code != null) {
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.add("code", code);
            map.add("client_id", "wz-app");
            map.add("client_secret", "123");
            map.add("redirect_uri", "http://localhost:8083/index.html");
            map.add("grant_type", "authorization_code");
            //獲取令牌
            Map<String,String> resp = restTemplate.postForObject("http://localhost:8081/oauth/token", map, Map.class);
            String access_token = resp.get("access_token");

            //請求資源
            System.out.println("令牌: "+access_token);
            HttpHeaders headers = new HttpHeaders();
            headers.add("Authorization", "Bearer " + access_token);
            HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
            ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8082/admin/res", HttpMethod.GET, httpEntity, String.class);
            model.addAttribute("token","令牌:"+access_token);
            model.addAttribute("res", "資源"+entity.getBody());
        }
        return "index";
    }
}

下面我們先分析一下預(yù)期的流程,然后再來測試看是否符合預(yù)期:

OAuth2.0從入門到實戰(zhàn)(附github地址)

下面通過測試來走一遍流程:

首先進(jìn)入第三方應(yīng)用首頁:

OAuth2.0從入門到實戰(zhàn)(附github地址)

點擊第三方登錄:通過admin賬號 登錄

OAuth2.0從入門到實戰(zhàn)(附github地址)

授權(quán):

OAuth2.0從入門到實戰(zhàn)(附github地址)

授權(quán)后我們可以看到會url上會帶有code,并且獲得了令牌和資源:

OAuth2.0從入門到實戰(zhàn)(附github地址)

這里僅僅是一個簡單的例子,為了方便熟悉OAuth2.0的授權(quán)碼模式全流程。access_token通常會通過一個定時任務(wù)來維護(hù),不需要每次請求頁面都去獲取,定期更新即可。

案例分析與優(yōu)化

通過上邊的例子,我們發(fā)現(xiàn)我們大部分的存儲都是在內(nèi)存中做的。我們可以從以下幾個方面進(jìn)行簡單的優(yōu)化:

  • 令牌的存儲位置
  • 客戶端信息入庫
  • 第三方應(yīng)用優(yōu)化
令牌的存儲位置

在我們配置授權(quán)碼的時候,將授權(quán)碼和令牌都存儲在了內(nèi)存中,我們可以看看TokenStroe的類圖:

OAuth2.0從入門到實戰(zhàn)(附github地址)

  1. InMemoryTokenStore,這是我們之前使用的,也是系統(tǒng)默認(rèn)的,就是將 access_token 存到內(nèi)存中,單機(jī)應(yīng)用這個沒有問題,但是在分布式環(huán)境下不推薦。
  2. JdbcTokenStore,看名字就知道,這種方式令牌會被保存到數(shù)據(jù)中,這樣就可以方便的和其他應(yīng)用共享令牌信息。
  3. JwtTokenStore,這個其實不是存儲,因為使用了 jwt 之后,在生成的 jwt 中就有用戶的所有信息,服務(wù)端不需要保存,這也是無狀態(tài)登錄。
  4. RedisTokenStore,這個很明顯就是將 access_token 存到 redis 中。
  5. JwkTokenStore,將 access_token 保存到 JSON Web Key。

雖然這里支持的方案比較多,但是我們常用的實際上主要是兩個,RedisTokenStore 和 JwtTokenStore

客戶端信息存儲

客戶端也就是第三方app的信息,之前我們也是直接寫在內(nèi)存中,同樣我們可以通過ClientDetailsService的類圖發(fā)現(xiàn)其提供的存儲方法:

OAuth2.0從入門到實戰(zhàn)(附github地址)

除了內(nèi)存的方式,只有額外數(shù)據(jù)庫的存儲的方式,通過源碼可以分析出數(shù)據(jù)庫的結(jié)構(gòu):

DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details` (
  `client_id` varchar(48) NOT NULL,
  `resource_ids` varchar(256) DEFAULT NULL,
  `client_secret` varchar(256) DEFAULT NULL,
  `scope` varchar(256) DEFAULT NULL,
  `authorized_grant_types` varchar(256) DEFAULT NULL,
  `web_server_redirect_uri` varchar(256) DEFAULT NULL,
  `authorities` varchar(256) DEFAULT NULL,
  `access_token_validity` int(11) DEFAULT NULL,
  `refresh_token_validity` int(11) DEFAULT NULL,
  `additional_information` varchar(4096) DEFAULT NULL,
  `autoapprove` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
第三方應(yīng)用優(yōu)化

我們上面分析了,demo中的令牌不能自動續(xù)期,我們可以通過一個TokenTask來管理Token:

    @GetMapping("/index.html")
    public String res(String code, Model model) {
        model.addAttribute("res", tokenTask.getData(code));
        return "index";
    }
@Component
@Slf4j
public class TokenTask {
    @Autowired
    RestTemplate restTemplate;
    public String access_token = "";
    public String refresh_token = "";

    public String getData(String code) {
        if ("".equals(access_token) && code != null) {
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.add("code", code);
            map.add("client_id", "wz-app");
            map.add("client_secret", "123");
            map.add("redirect_uri", "http://localhost:8083/index.html");
            map.add("grant_type", "authorization_code");
            Map<String, String> resp = restTemplate.postForObject("http://localhost:8081/oauth/token", map, Map.class);
            access_token = resp.get("access_token");
            refresh_token = resp.get("refresh_token");
            return loadDataFromResServer();
        } else {
            return loadDataFromResServer();
        }
    }

    private String loadDataFromResServer() {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.add("Authorization", "Bearer " + access_token);
            HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
            ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8082/admin/res", HttpMethod.GET, httpEntity, String.class);
            log.info("資源數(shù)據(jù)為=={}",entity.getBody());
            return entity.getBody();
        } catch (RestClientException e) {
            return "未加載";
        }
    }

    @Scheduled(cron = "0 55 0/1 * * ?")
    public void tokenTask() {
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("client_id", "wz-app");
        map.add("client_secret", "123");
        map.add("refresh_token", refresh_token);
        map.add("grant_type", "refresh_token");
        Map<String, String> resp = restTemplate.postForObject("http://localhost:8081/oauth/token", map, Map.class);
        log.debug("定時任務(wù)獲取的data=={}",resp);
        access_token = resp.get("access_token");
        refresh_token = resp.get("refresh_token");
    }
}

OAuth2.0 單點登錄實例

單點登錄是我們在分布式系統(tǒng)中很常見的一個需求。

分布式系統(tǒng)由多個不同的子系統(tǒng)組成,而我們在使用系統(tǒng)的時候,只需要登錄一次即可,這樣其他系統(tǒng)都認(rèn)為用戶已經(jīng)登錄了,不用再去登錄。

下面的例子通過 Spring Boot+OAuth2 做單點登錄,利用 @EnableOAuth2Sso 注解快速實現(xiàn)單點登錄功能。

我們要實現(xiàn)單點登錄,需要我們再提供多個客戶端,并且當(dāng)這個客戶端登錄成功后,其它客戶端不需要再登錄。

認(rèn)證與資源服務(wù)依舊采用上個例子中的服務(wù)。我們再來開發(fā)兩個客戶端來實現(xiàn)單點登錄的效果。

項目 端口 備注
auth-res-server 8086 鑒權(quán)與資源中心
client1 8084 第三方應(yīng)用client1
client2 8085 第三方應(yīng)用client2

認(rèn)證與資源中心配置

這里為了簡便,采用認(rèn)證與資源使用一個服務(wù)的方式。

依賴:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

項目創(chuàng)建成功之后,這個模塊由于要扮演授權(quán)服務(wù)器+資源服務(wù)器的角色,所以我們先在這個項目的啟動類上添加 @EnableResourceServer 注解,表示這是一個資源服務(wù)器:

@SpringBootApplication
@EnableResourceServer
public class AuthResServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(AuthResServerApplication.class, args);
    }

}

接下來我們進(jìn)行授權(quán)服務(wù)器的配置,由于資源服務(wù)器和授權(quán)服務(wù)器合并在一起,因此授權(quán)服務(wù)器的配置要省事很多:

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("sso")
                .secret(passwordEncoder.encode("123"))
                .autoApprove(true)//自動授權(quán)
                .redirectUris("http://localhost:8084/login", "http://localhost:8085/login")
                .scopes("user")
                .accessTokenValiditySeconds(7200)
                .authorizedGrantTypes("authorization_code");

    }
}

接下來我們再來配置 Spring Security:

@Configuration
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/login.html", "/css/**", "/js/**", "/images/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatchers()
                .antMatchers("/login")
                .antMatchers("/oauth/authorize")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.html") //自定義的一個登錄頁面
                .loginProcessingUrl("/login")
                .permitAll()
                .and()
                .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("wz")
                .password(passwordEncoder().encode("123"))
                .roles("admin");
    }
}

添加一個暴露用戶信息的資源接口:

 @GetMapping("/user")
    public Principal getCurrentUser(Principal principal) {
        return principal;
    }

客戶端服務(wù)創(chuàng)建

我們需要創(chuàng)建兩個客戶端,名字分別為client1client2。都添加Spring Security + Oauth2的依賴。

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

然后我們配置以下客戶端的Spring Security

/**
 * @Description: SecurityConfig,client中的所有接口都需要認(rèn)證之后才能訪問
 * @Author: Ze WANG
 **/
@Configuration
@EnableOAuth2Sso //開啟單點登錄的功能
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().csrf().disable();
    }
}

提供測試接口:

/**
 * @Description: UserController,返回當(dāng)前登錄的用戶的姓名和角色信息
 * @Author: Ze WANG
 **/
@RestController
public class UserController {
    @GetMapping("/user")
    public String user() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication.getName() + Arrays.toString(authentication.getAuthorities().toArray());
    }
}

配置OAuth2的相關(guān)信息

# client-secret
security.oauth2.client.client-secret=123
# client-id
security.oauth2.client.client-id=sso
# get user authorize
security.oauth2.client.user-authorization-uri=http://localhost:8086/oauth/authorize
# get token
security.oauth2.client.access-token-uri=http://localhost:8086/oauth/token
# user info
security.oauth2.resource.user-info-uri=http://localhost:8086/user

#port
server.port=8084

#cookie-name
server.servlet.session.cookie.name=client1_cookie

單點登錄測試

  1. 直接訪問client1/user接口,會要求我們登錄,重定向到client1/login,由于我們配置了@EnableOAuth2Sso所以這個操作會被攔截下來,根據(jù)我們的配置自動發(fā)起請求去獲取授權(quán)碼。

    OAuth2.0從入門到實戰(zhàn)(附github地址)

    OAuth2.0從入門到實戰(zhàn)(附github地址)

  2. 跳轉(zhuǎn)到鑒權(quán)中心的/oauth/authorize,需要先登錄,登錄之后,授權(quán),授權(quán)后獲得授權(quán)碼。

    OAuth2.0從入門到實戰(zhàn)(附github地址)

    OAuth2.0從入門到實戰(zhàn)(附github地址)

  3. 獲取到授權(quán)碼之后,這個時候會重定向到我們 client1 的 login 頁面,但是實際上我們的 client1 其實是沒有登錄頁面的,所以這個操作依然會被攔截,此時攔截到的地址包含有授權(quán)碼,拿著授權(quán)碼,在 OAuth2ClientAuthenticationProcessingFilter 類中向鑒權(quán)中心發(fā)起請求,就能拿到 access_token 了。

  4. 拿到 access_token 之后,接下來在向我們配置的 user-info-uri 地址發(fā)送請求,獲取登錄用戶信息。

    OAuth2.0從入門到實戰(zhàn)(附github地址)

  5. 這時候在請求client2的/user接口,不需要手動再次登錄。

    OAuth2.0從入門到實戰(zhàn)(附github地址)

github地址:Oauth2-sso-demo

參考:

[1].OAuth 2.0 的一個簡單解釋 - 阮一峰的網(wǎng)絡(luò)日志 (ruanyifeng.com)

[2].OAuth 2.0 的四種方式 - 阮一峰的網(wǎng)絡(luò)日志 (ruanyifeng.com)文章來源地址http://www.zghlxwxcb.cn/news/detail-404138.html

到了這里,關(guān)于OAuth2.0從入門到實戰(zhàn)(附github地址)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • SpringBoot3.0 + SpringSecurity6.0 +OAuth2 使用Github作為授權(quán)登錄

    SpringBoot3.0 + SpringSecurity6.0 +OAuth2 使用Github作為授權(quán)登錄

    1.1 OAuth是什么 開放授權(quán)(OAuth)是一個開放標(biāo)準(zhǔn),允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲的私密的資源(如照片,視頻,聯(lián)系人列表),而無需將用戶名和密碼提供給第三方應(yīng)用。 OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務(wù)提供

    2024年02月11日
    瀏覽(23)
  • 12-SpringSecurity:通過OAuth2集成Github登錄,字節(jié)跳動網(wǎng)絡(luò)工程師的面試

    12-SpringSecurity:通過OAuth2集成Github登錄,字節(jié)跳動網(wǎng)絡(luò)工程師的面試

    (1) 注冊應(yīng)用 在Github注冊一個應(yīng)用,生成 client-id , client-secret 。 注意這里的Home頁: http://localhost:8080 ,以及回調(diào)地址: http://localhost:8080/login/oauth2/code/github (2) 配置 application.yml spring: security: oauth2: client: registration: github: client-id: client-secret: (3) 啟動應(yīng)用 為了看到登錄

    2024年04月10日
    瀏覽(22)
  • Spring Security實現(xiàn)OAuth2協(xié)議及實戰(zhàn)

    Spring Security實現(xiàn)OAuth2協(xié)議及實戰(zhàn)

    文章篇幅較長,愿讀者耐心看完。如有不足之處,請指正。 一.OAuth2介紹 1.1 OAuth2是什么 怎么用 OAuth2是目前最流行的授權(quán)協(xié)議,用來授權(quán)第三方應(yīng)用,獲取用戶數(shù)據(jù)。 舉個例子:快遞員想要進(jìn)入小區(qū),有3種方式。1是業(yè)主遠(yuǎn)程開門,2是業(yè)主告訴門禁密碼,3是使用令牌(Oaut

    2024年02月08日
    瀏覽(21)
  • 微服務(wù)安全Spring Security Oauth2實戰(zhàn)

    微服務(wù)安全Spring Security Oauth2實戰(zhàn)

    Spring Authorization Server 是一個框架,它提供了 OAuth 2.1 和 OpenID Connect 1.0 規(guī)范以及其他相關(guān)規(guī)范的實現(xiàn)。它建立在 Spring Security 之上,為構(gòu)建 OpenID Connect 1.0 身份提供者和 OAuth2 授權(quán)服務(wù)器產(chǎn)品提供了一個安全、輕量級和可定制的基礎(chǔ)。說白了,Spring Authorization Server 就是一個**認(rèn)

    2024年02月03日
    瀏覽(28)
  • Spring Security OAuth2.0(3):Spring Security簡單入門

    Spring Security OAuth2.0(3):Spring Security簡單入門

    Spring Security 快速入門。 本章代碼已分享至Gitee:https://gitee.com/lengcz/security-spring-security qquad Spring Secutiry 是一個能夠為基于Spring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問控制解決方案的安全框架。由于它是Spring生態(tài)系統(tǒng)的一員,因此它伴隨著整個Spring生態(tài)系統(tǒng)不斷修正、升級,

    2024年02月13日
    瀏覽(28)
  • Springboot 3 + Spring Security 6 + OAuth2 入門級最佳實踐

    Springboot 3 + Spring Security 6 + OAuth2 入門級最佳實踐

    當(dāng)我的項目基于 SpringBoot 3 而我想使用Spring Security,最終不幸得到WebSecurityConfigurerAdapter被廢棄的消息。本文檔就是在這樣的情況下產(chǎn)生的。 應(yīng)該基于: SpringBoot 3.x版本 JDK 17 在瀏覽器訪問默認(rèn)8080端口可以得到默認(rèn)授權(quán)頁面: 用戶名為user,密碼在控制臺中自動生成: 寫一個測

    2024年02月08日
    瀏覽(62)
  • Spring Authorization Server入門 (一) 初識SpringAuthorizationServer和OAuth2.1協(xié)議

    Spring Authorization Server入門 (一) 初識SpringAuthorizationServer和OAuth2.1協(xié)議

    經(jīng)過近些年網(wǎng)絡(luò)和設(shè)備的不斷發(fā)展,之前的oauth2.0發(fā)布的授權(quán)協(xié)議標(biāo)準(zhǔn)已經(jīng)遠(yuǎn)遠(yuǎn)不能滿足現(xiàn)在的場景和需求,根據(jù)其安全最佳實踐,在oauth2.0的基礎(chǔ)上移除了一些不安全的授權(quán)方式,并且對擴(kuò)展協(xié)議進(jìn)行整合。該協(xié)議定義了一系列關(guān)于授權(quán)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn),允許用戶授權(quán)第三方

    2024年02月11日
    瀏覽(23)
  • 開放平臺實現(xiàn)安全的身份認(rèn)證與授權(quán)原理與實戰(zhàn):學(xué)習(xí)OAuth2.0之PKCE

    隨著互聯(lián)網(wǎng)的不斷發(fā)展,我們的生活中越來越多的服務(wù)都需要我們的身份認(rèn)證和授權(quán)。例如,我們在使用某些網(wǎng)站或應(yīng)用程序時,需要通過賬號和密碼進(jìn)行身份認(rèn)證,以便于保護(hù)我們的個人信息和數(shù)據(jù)。同時,當(dāng)我們使用某些第三方應(yīng)用程序時,這些應(yīng)用程序需要我們授權(quán)訪

    2024年04月16日
    瀏覽(25)
  • 開放平臺實現(xiàn)安全的身份認(rèn)證與授權(quán)原理與實戰(zhàn):整理OAuth2.0各種開發(fā)指南

    OAuth 2.0 是一種基于標(biāo)準(zhǔn) HTTP 的身份驗證和授權(quán)機(jī)制,它允許用戶授予第三方應(yīng)用程序訪問他們在其他服務(wù)(如社交網(wǎng)絡(luò)、電子郵件服務(wù)器或云存儲服務(wù))的數(shù)據(jù)。OAuth 2.0 的目標(biāo)是提供一種簡化的方法,使得用戶可以安全地授予第三方應(yīng)用程序訪問他們的數(shù)據(jù),而無需將他們的密

    2024年04月27日
    瀏覽(21)
  • Spring Authorization Server 1.1 擴(kuò)展實現(xiàn) OAuth2 密碼模式與 Spring Cloud 的整合實戰(zhàn)

    Spring Authorization Server 1.1 擴(kuò)展實現(xiàn) OAuth2 密碼模式與 Spring Cloud 的整合實戰(zhàn)

    項目源碼 :youlai-mall 通過 Spring Cloud Gateway 訪問認(rèn)證中心進(jìn)行認(rèn)證并獲取得到訪問令牌。 再根據(jù)訪問令牌 access_token 獲取當(dāng)前登錄的用戶信息。 Spring Security OAuth2 的最終版本是2.5.2,并于2022年6月5日正式宣布停止維護(hù)。Spring 官方為此推出了新的替代產(chǎn)品,即 Spring Authorization

    2024年02月04日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包