<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
OAuth 是一個開放標準,該標準允許使用者讓第三方應用存取該使用者在某一網站上儲存的私密資源(如頭像、照片、視訊等),而在這個過程中無須將使用者名稱和密碼提供給第三方應用。
實現這一功能是通過一個令牌(token),而不是使用者名稱和密碼來存取他們存放在特定服務提供者的資料。每一個令牌授權一個特定的網站在特定的時間段記憶體取特定的資源。
這樣 OAuth 讓使用者可以授權第三方網站靈活的存取儲存在另一些資源伺服器的特定資訊,而非所有內容。例如,使用者想通過 QQ 登入知乎,這時知乎就是一個第三方應用,知乎要存取使用者的一些基本資訊就需要得到使用者的授權,如果使用者把自己的 QQ 使用者名稱和密碼告訴知乎,那麼知乎就能存取使用者的所有資料,並且只有使用者修改密碼才能收回許可權,這種授權方式安全隱患很大,如果使用 OAuth ,就能很好的解決這一問題。
採用令牌的方式可以讓使用者靈活的對第三方應用授權或者收回許可權。OAuth 2 是 OAuth 協定的下一版本,但不向下相容 OAuth 1.0 。
OAuth 2 關注使用者端開發者的簡易型,同時為Web應用、桌面應用,移動裝置、起居室裝置提供專門的認證流程。傳統的 Web 開發登入認證一般都是基於 Session 的,但是前後端分離的架構中繼續使用 Session 會有許多不便,因為行動端(Android、IOS、微信小程式等)要麼不支援 Cookie(微信小程式),要麼使用非常不便,對於這些問題,使用 OAuth 2 認證都能解決。
先了解 OAuth 2 中幾個基本的角色
一般來說,授權伺服器和資源伺服器可以是同一臺伺服器。
步驟01:使用者端(第三方應用)向用戶請求授權。
步驟02:使用者單擊使用者端所呈現的服務授權頁面上的同意授權按鈕後,伺服器端返回一個授權許可憑證給使用者端。
步驟03:使用者端拿著授權許可證去授權伺服器申請令牌。
步驟04:授權伺服器驗證資訊無誤後,發放令牌給使用者端。
步驟05:使用者端拿著令牌去資源伺服器存取資源。
步驟06:資源伺服器驗證令牌無誤後開放資源。
OAuth 協定的授權模式共分為 4 種,如下
4 種模式各有千秋,分別適用於不同的開發場景,開發者根據實際情況進行選擇
此處介紹的是在前後端分離應用(或為行動端、微信小程式等)提供的認證伺服器中如何搭建 OAuth 服務,因此主要介紹密碼模式。
建立 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 協定是在 Spring Security 的基礎上完成的,因此首先要新增 Spring Security 依賴,要用到 OAuth 2,因此新增 OAuth 2 相關依賴,令牌可以儲存在 Redis 快取伺服器上,同時 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
授權伺服器和資源伺服器可以是同一臺伺服器,也可以是不同伺服器,此處假設是同一臺伺服器,通過不同的設定分別開啟授權伺服器和資源伺服器,首先是授權伺服器:
@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(); } }
程式碼解釋:
@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(); } }
程式碼解釋:
@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 將注入授權伺服器設定類中使用,另外,這裡的 HttpSecurity 設定主要是設定 /oauth/** 模式的 URL ,這一類的請求直接放行。在 Spring Security 設定和資源伺服器設定中,一共涉及兩個 HttpSecurity ,其中 Spring Security 中的設定優先順序高於資源伺服器中的設定,即請求地址先經過 Spring Security 的 HttpSecurity ,再經過資源伺服器的 HttpSecurity。
首先建立三個簡單的請求地址
@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"; } }
根據前文的設定,要請求這三個地址,分別需要 admin 角色、user 角色以及登入後存取。
所有都設定完成後,啟動 Redis 伺服器,再啟動 Spring Boot 專案,首先傳送一個 POST 請求獲取 token,請求地址如下(注意這裡是一個 POST 請求,為了顯示方便,將引數寫在位址列中):http://localhost:8080/oauth/token?username=sang&password=123&grant_type=password&client_id=password&scope=all&client_secret=123
請求地址中包含的引數有使用者名稱、密碼、授權模式、使用者端 id 、scope 以及使用者端密碼,基本就是授權伺服器中所設定的資料,請求結果如圖
其中 access_token 是獲取其它資源時要用的令牌,refresh_token 用來重新整理令牌,expires_in 表示 access_token 過期時間,當 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 ,同事授權模式設定為 refresh_token ,在獲取的結果中 access_token 會變化,同時 access_token 有效期也會變化,如圖
接下來存取所有資源,攜帶上 access_token 引數即可,例如 /user/hello 介面:http://localhost:8080/user/hello?access_token=0497e4bc-df37-460e-8755-b813b9dbf36a,存取結果如圖
如果非法存取一個資源,例如 sang 使用者存取 /admin/hello 介面,結果如圖
到此,一個 password 模式的 OAuth 認證體系就搭建成功了。
OAuth 中的認證模式有 4 中,開發者需要結合自己開發的實際情況選擇其中一種,此處介紹的是在前後端分離應用中常用的 password 模式,其它的授權模式也都有自己的使用場景。
整體來講,Spring Security OAuth 2 的使用還是較複雜的,設定也比較繁瑣,如果開發者的應用場景比較簡單,完全可以按照此處介紹的授權流程自己搭建 OAuth 2 認證體系。
到此這篇關於SpringBoot淺析安全管理之OAuth2框架的文章就介紹到這了,更多相關SpringBoot OAuth2框架內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45