日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

@order注解_Spring Boot+OAuth2,一个注解搞定单点登录!

發(fā)布時間:2025/3/19 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 @order注解_Spring Boot+OAuth2,一个注解搞定单点登录! 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今日干貨

剛剛發(fā)表查看:66666回復(fù):666

公眾號后臺回復(fù) ssm,免費獲取松哥純手敲的 SSM 框架學(xué)習(xí)干貨。

需要先說一下,松哥最近寫的教程,都是成系列的,有一些重復(fù)的東西寫來寫去就沒意思了,所以每一篇文章都默認(rèn)大家已經(jīng)懂了前面的內(nèi)容了,因此下文有任何看不懂的地方,建議一定先看下相關(guān)系列:

「Spring Security 系列:」

  • 挖一個大坑,Spring Security 開搞!
  • 松哥手把手帶你入門 Spring Security,別再問密碼怎么解密了
  • 手把手教你定制 Spring Security 中的表單登錄
  • Spring Security 做前后端分離,咱就別做頁面跳轉(zhuǎn)了!統(tǒng)統(tǒng) JSON 交互
  • Spring Security 中的授權(quán)操作原來這么簡單
  • Spring Security 如何將用戶數(shù)據(jù)存入數(shù)據(jù)庫?
  • Spring Security+Spring Data Jpa 強強聯(lián)手,安全管理只有更簡單!
  • 「OAuth2 系列:」

  • 做微服務(wù)繞不過的 OAuth2,松哥也來和大家扯一扯
  • 這個案例寫出來,還怕跟面試官扯不明白 OAuth2 登錄流程?
  • 死磕 OAuth2,教練我要學(xué)全套的!
  • OAuth2 令牌還能存入 Redis ?越玩越溜!
  • 想讓 OAuth2 和 JWT 在一起愉快玩耍?請看松哥的表演
  • 和大家分享一點微服務(wù)架構(gòu)中的安全管理思路
  • 好了,開始今天的正文。

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

    分布式系統(tǒng)由多個不同的子系統(tǒng)組成,而我們在使用系統(tǒng)的時候,只需要登錄一次即可,這樣其他系統(tǒng)都認(rèn)為用戶已經(jīng)登錄了,不用再去登錄。前面和小伙伴們分享了 OAuth2+JWT 的登錄方式,這種無狀態(tài)登錄實際上天然的滿足單點登錄的需求,可以參考:想讓 OAuth2 和 JWT 在一起愉快玩耍?請看松哥的表演。

    當(dāng)然大家也都知道,無狀態(tài)登錄也是有弊端的。

    所以今天松哥想和大家說一說 Spring Boot+OAuth2 做單點登錄,利用 @EnableOAuth2Sso 注解快速實現(xiàn)單點登錄功能。

    松哥依然建議大家在閱讀本文時,先看看本系列前面的文章,這有助于更好的理解本文。

    1.項目創(chuàng)建

    前面的案例中,松哥一直都把授權(quán)服務(wù)器和資源服務(wù)器分開創(chuàng)建,今天這個案例,為了省事,我就把授權(quán)服務(wù)器和資源服務(wù)器搭建在一起(不過相信大家看了前面的文章,應(yīng)該也能自己把這兩個服務(wù)器拆分開)。

    所以,今天我們一共需要三個服務(wù):

    項目端口描述
    auth-server1111授權(quán)服務(wù)器+資源服務(wù)器
    client11112子系統(tǒng)1
    client21113子系統(tǒng)2

    auth-server 用來扮演授權(quán)服務(wù)器+資源服務(wù)器的角色,client1 和 client2 則分別扮演子系統(tǒng)的角色,將來等 client1 登錄成功之后,我們也就能訪問 client2 了,這樣就能看出來單點登錄的效果。

    我們創(chuàng)建一個名為 oauth2-sso 的 Maven 項目作為父工程即可。

    2.統(tǒng)一認(rèn)證中心

    接下來我們來搭建統(tǒng)一認(rèn)證中心。

    首先我們創(chuàng)建一個名為 auth-server 的 module,創(chuàng)建時添加如下依賴:

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

    @SpringBootApplication
    @EnableResourceServer
    public?class?AuthServerApplication?{

    ????public?static?void?main(String[]?args)?{
    ????????SpringApplication.run(AuthServerApplication.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("javaboy")
    ????????????????.secret(passwordEncoder.encode("123"))
    ????????????????.autoApprove(true)
    ????????????????.redirectUris("http://localhost:1112/login",?"http://localhost:1113/login")
    ????????????????.scopes("user")
    ????????????????.accessTokenValiditySeconds(7200)
    ????????????????.authorizedGrantTypes("authorization_code");

    ????}
    }

    這里我們只需要簡單配置一下客戶端的信息即可,這里的配置很簡單,前面的文章也講過了,大家要是不懂,可以參考本系列前面的文章:這個案例寫出來,還怕跟面試官扯不明白 OAuth2 登錄流程?。

    當(dāng)然這里為了簡便,客戶端的信息配置是基于內(nèi)存的,如果大家想將客戶端信息存入數(shù)據(jù)庫中,也是可以的,參考:OAuth2 令牌還能存入 Redis ?越玩越溜!

    接下來我們再來配置 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("sang")
    ????????????????.password(passwordEncoder().encode("123"))
    ????????????????.roles("admin");
    ????}
    }

    關(guān)于 Spring Security 的配置,如果小伙伴們不懂,可以看看松哥最近正在連載的 Spring Security 系列。

    我這里來大致捋一下:

  • 首先提供一個 BCryptPasswordEncoder 的實例,用來做密碼加解密用。
  • 由于我自定義了登錄頁面,所以在 WebSecurity 中對這些靜態(tài)資源方形。
  • HttpSecurity 中,我們對認(rèn)證相關(guān)的端點放行,同時配置一下登錄頁面和登錄接口。
  • AuthenticationManagerBuilder 中提供一個基于內(nèi)存的用戶(小伙伴們可以根據(jù) Spring Security 系列第 7 篇文章自行調(diào)整為從數(shù)據(jù)庫加載)。
  • 另外還有一個比較關(guān)鍵的地方,因為資源服務(wù)器和授權(quán)服務(wù)器在一起,所以我們需要一個 @Order 注解來提升 Spring Security 配置的優(yōu)先級。
  • SecurityConfig 和 AuthServerConfig 都是授權(quán)服務(wù)器需要提供的東西(如果小伙伴們想將授權(quán)服務(wù)器和資源服務(wù)器拆分,請留意這句話),接下來,我們還需要提供一個暴露用戶信息的接口(如果將授權(quán)服務(wù)器和資源服務(wù)器分開,這個接口將由資源服務(wù)器提供):

    @RestController
    public?class?UserController?{
    ????@GetMapping("/user")
    ????public?Principal?getCurrentUser(Principal?principal)?{
    ????????return?principal;
    ????}
    }

    最后,我們在 application.properties 中配置一下項目端口:

    server.port=1111

    另外,松哥自己提前準(zhǔn)備了一個登錄頁面,如下:

    將登錄頁面相關(guān)的 html、css、js 等拷貝到 resources/static 目錄下:

    這個頁面很簡單,就是一個登錄表單而已,我把核心部分列出來:

    <form?action="/login"?method="post">
    ????<div?class="input">
    ????????<label?for="name">用戶名label>
    ????????<input?type="text"?name="username"?id="name">
    ????????<span?class="spin">span>
    ????div>
    ????<div?class="input">
    ????????<label?for="pass">密碼label>
    ????????<input?type="password"?name="password"?id="pass">
    ????????<span?class="spin">span>
    ????div>
    ????<div?class="button?login">
    ????????<button?type="submit">
    ????????????<span>登錄span>
    ????????????<i?class="fa?fa-check">i>
    ????????button>
    ????div>
    form>

    注意一下 action 提交地址不要寫錯即可。

    「文末可以下載源碼?!?/strong>

    如此之后,我們的統(tǒng)一認(rèn)證登錄平臺就算是 OK 了。

    3.客戶端創(chuàng)建

    接下來我們來創(chuàng)建一個客戶端項目,創(chuàng)建一個名為 client1 的 Spring Boot 項目,添加如下依賴:

    項目創(chuàng)建成功之后,我們來配置一下 Spring Security:

    @Configuration
    @EnableOAuth2Sso
    public?class?SecurityConfig?extends?WebSecurityConfigurerAdapter?{
    ????@Override
    ????protected?void?configure(HttpSecurity?http)?throws?Exception?{
    ????????http.authorizeRequests().anyRequest().authenticated().and().csrf().disable();
    ????}
    }

    這段配置很簡單,就是說我們 client1 中所有的接口都需要認(rèn)證之后才能訪問,另外添加一個 @EnableOAuth2Sso 注解來開啟單點登錄功能。

    接下來我們在 client1 中再來提供一個測試接口:

    @RestController
    public?class?HelloController?{
    ????@GetMapping("/hello")
    ????public?String?hello()?{
    ????????Authentication?authentication?=?SecurityContextHolder.getContext().getAuthentication();
    ????????return?authentication.getName()?+?Arrays.toString(authentication.getAuthorities().toArray());
    ????}
    }

    這個測試接口返回當(dāng)前登錄用戶的姓名和角色信息。

    接下來我們需要在 client1 的 application.properties 中配置 oauth2 的相關(guān)信息:

    security.oauth2.client.client-secret=123
    security.oauth2.client.client-id=javaboy
    security.oauth2.client.user-authorization-uri=http://localhost:1111/oauth/authorize
    security.oauth2.client.access-token-uri=http://localhost:1111/oauth/token
    security.oauth2.resource.user-info-uri=http://localhost:1111/user

    server.port=1112

    server.servlet.session.cookie.name=s1

    這里的配置也比較熟悉,我們來看一下:

  • client-secret 是客戶端密碼。
  • client-id 是客戶端 id。
  • user-authorization-uri 是用戶授權(quán)的端點。
  • access-token-uri 是獲取令牌的端點。
  • user-info-uri 是獲取用戶信息的接口(從資源服務(wù)器上獲取)。
  • 最后再配置一下端口,然后給 cookie 取一個名字。
  • 如此之后,我們的 client1 就算是配置完成了。

    按照相同的方式,我們再來配置一個 client2,client2 和 client1 一模一樣,就是 cookie 的名字不同(隨意取,不相同即可)。

    4.測試

    接下來,我們分別啟動 auth-server、client1 和 client2,首先我們嘗試去方式 client1 中的 hello 接口,這個時候會自動跳轉(zhuǎn)到統(tǒng)一認(rèn)證中心:

    然后輸入用戶名密碼進(jìn)行登錄。

    登錄成功之后,會自動跳轉(zhuǎn)回 client1 的 hello 接口,如下:

    此時我們再去訪問 client2 ,發(fā)現(xiàn)也不用登錄了,直接就可以訪問:

    OK,如此之后,我們的單點登錄就成功了。

    5.流程解析

    最后,我再來和小伙伴們把上面代碼的一個執(zhí)行流程捋一捋:

  • 首先我們?nèi)ピL問 client1 的 /hello 接口,但是這個接口是需要登錄才能訪問的,因此我們的請求被攔截下來,攔截下來之后,系統(tǒng)會給我們重定向到 client1 的 /login 接口,這是讓我們?nèi)サ卿洝?/li>
  • 當(dāng)我們?nèi)ピL問 client1 的登錄接口時,由于我們配置了 @EnableOAuth2Sso 注解,這個操作會再次被攔截下來,單點登錄攔截器會根據(jù)我們在 application.properties 中的配置,自動發(fā)起請求去獲取授權(quán)碼:
  • 在第二步發(fā)送的請求是請求 auth-server 服務(wù)上的東西,這次請求當(dāng)然也避免不了要先登錄,所以再次重定向到 auth-server 的登錄頁面,也就是大家看到的統(tǒng)一認(rèn)證中心。
  • 在統(tǒng)一認(rèn)真中心我們完成登錄功能,登錄完成之后,會繼續(xù)執(zhí)行第二步的請求,這個時候就可以成功獲取到授權(quán)碼了。
  • 獲取到授權(quán)碼之后,這個時候會重定向到我們 client1 的 login 頁面,但是實際上我們的 client1 其實是沒有登錄頁面的,所以這個操作依然會被攔截,此時攔截到的地址包含有授權(quán)碼,拿著授權(quán)碼,在 OAuth2ClientAuthenticationProcessingFilter 類中向 auth-server 發(fā)起請求,就能拿到 access_token 了(參考:這個案例寫出來,還怕跟面試官扯不明白 OAuth2 登錄流程?)。
  • 在第五步拿到 access_token 之后,接下來在向我們配置的 user-info-uri 地址發(fā)送請求,獲取登錄用戶信息,拿到用戶信息之后,在 client1 上自己再走一遍 Spring Security 登錄流程,這就 OK 了。
  • OK,本文和小伙伴們聊了一些 SpringBoot +OAuth2 單點登錄的問題,完整案例下載地址:https://github.com/lenve/oauth2-samples

    如果小伙伴們覺得有用的話,記得點個在看鼓勵下松哥。

    今日干貨

    剛剛發(fā)表查看:13500回復(fù):135

    公眾號后臺回復(fù) SpringBoot,免費獲取 274 頁SpringBoot修煉手冊。

    總結(jié)

    以上是生活随笔為你收集整理的@order注解_Spring Boot+OAuth2,一个注解搞定单点登录!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。