javascript
@order注解_Spring Boot+OAuth2,一个注解搞定单点登录!
今日干貨
剛剛發(fā)表查看:66666回復(fù):666公眾號后臺回復(fù) ssm,免費獲取松哥純手敲的 SSM 框架學(xué)習(xí)干貨。
需要先說一下,松哥最近寫的教程,都是成系列的,有一些重復(fù)的東西寫來寫去就沒意思了,所以每一篇文章都默認(rèn)大家已經(jīng)懂了前面的內(nèi)容了,因此下文有任何看不懂的地方,建議一定先看下相關(guān)系列:
「Spring Security 系列:」
「OAuth2 系列:」
好了,開始今天的正文。
單點登錄是我們在分布式系統(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-server | 1111 | 授權(quán)服務(wù)器+資源服務(wù)器 |
| client1 | 1112 | 子系統(tǒng)1 |
| client2 | 1113 | 子系統(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 系列。
我這里來大致捋一下:
SecurityConfig 和 AuthServerConfig 都是授權(quán)服務(wù)器需要提供的東西(如果小伙伴們想將授權(quán)服務(wù)器和資源服務(wù)器拆分,請留意這句話),接下來,我們還需要提供一個暴露用戶信息的接口(如果將授權(quán)服務(wù)器和資源服務(wù)器分開,這個接口將由資源服務(wù)器提供):
@RestControllerpublic?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 中再來提供一個測試接口:
@RestControllerpublic?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=123security.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
這里的配置也比較熟悉,我們來看一下:
如此之后,我們的 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í)行流程捋一捋:
OK,本文和小伙伴們聊了一些 SpringBoot +OAuth2 單點登錄的問題,完整案例下載地址:https://github.com/lenve/oauth2-samples
如果小伙伴們覺得有用的話,記得點個在看鼓勵下松哥。
今日干貨
剛剛發(fā)表查看:13500回復(fù):135公眾號后臺回復(fù) SpringBoot,免費獲取 274 頁SpringBoot修煉手冊。
總結(jié)
以上是生活随笔為你收集整理的@order注解_Spring Boot+OAuth2,一个注解搞定单点登录!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stm32 ucosii消息队列 串口_
- 下一篇: springboot 访问html_Sp