springboot oauth2實現(xiàn)單點登錄實例
我們見過的很多網(wǎng)站,容許使用第三方賬號登錄,他不需要關注用戶信息,只需要用戶拿到授權碼就可以訪問。
oauth2是用來做三方登錄的,他的授權方式有好幾種,授權碼模式、密碼模式、隱式模式、客戶端模式。
oauth2認證的過程如下:一般我們請求一個需要登錄的網(wǎng)站A,會提示我們使用第三方網(wǎng)站C的用戶登錄,我們登錄,這時候需要我們授權,就是authorize,授權之后,會得到一個token,我們拿到這個token就可以訪問這個網(wǎng)站A了。A網(wǎng)站不關心C網(wǎng)站的用戶信息。
springsecurity結合oauth2可以做這個功能,這里給出一個springboot+security+oauth2的實例,這個實例很直觀,就是我們有兩個服務A,C,A是需要用戶登錄的網(wǎng)站,而C是授權服務器。當我們訪問A的資源:http://localhost:8000/hello,他會跳到C的服務器上登錄,登錄完成,授權,就直接調回來A網(wǎng)站,這里使用了單點登錄功能。
構建項目:我這里構建了一個父級項目securityoauth2,然后加入了兩個模塊:auth-server,client-1。
項目依賴:
securityoauth2->pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</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.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.3.2.RELEASE</version> </dependency> </dependencies> <modules> <module>auth-server</module> <module>client-1</module> </modules>
***********auth-server***************************************
AuthServerConfiguration.java
package com.xxx.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @Configuration @EnableAuthorizationServer public class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter{ @Autowired private PasswordEncoder passwordEncoder; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("client") .secret(passwordEncoder.encode("secret")) .autoApprove(true) .redirectUris("http://localhost:8000/login","http://localhost:8001/login") .scopes("user") .accessTokenValiditySeconds(7200) .authorizedGrantTypes("authorization_code"); } }
授權服務配置這里,主要設置client_id,以及secret,這里設置了自動授權autoApprove(true),就是我們輸入用戶名和密碼登錄之后,不會出現(xiàn)一個需要我們手動點擊authorize的按鈕進行授權。另外配置了redirect_uri,這個是必須的。最后還設置了授權類型,這里選擇的是授權碼模式。
SecurityConfiguration.java
package com.xxx.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @Order(1) @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder builder) throws Exception { builder.inMemoryAuthentication() .withUser("admin") .password(passwordEncoder().encode("admin")) .roles("admin"); } @Override protected void configure(HttpSecurity http) throws Exception { http.requestMatchers() .antMatchers("/login") .antMatchers("/oauth/authorize") .and() .authorizeRequests().anyRequest().authenticated() .and() .formLogin() .and() .csrf().disable(); } }
Security是做權限管理的,他需要配置用戶和密碼,這里采用內存保存的方式,將用戶名和密碼保存在內存中,而不是數(shù)據(jù)庫或者redis中,關于保存在哪里,對于了解oauth2來說,放在內存是最簡單的,省去了建表,做數(shù)據(jù)庫查詢的麻煩。
TestController.java
package com.xxx.web; import java.security.Principal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/test") public class TestController { @GetMapping("/user") public Principal currentUser(Principal principal) { return principal; } }
這個controller配置,不是用來測試訪問他的,而是用來做一個接口,給client-1使用,client-1配置文件中有個配置:security.oauth2.resource.user-info-uri就是配置的這個接口。
App.java
package com.xxx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; @SpringBootApplication @EnableResourceServer public class App { public static void main( String[] args ){ SpringApplication.run(App.class, args); } }
application.yaml //無配置,可以略
***********client-1*********************************************************
SecurityConfiguration.java
package com.xxx.config; import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @SuppressWarnings("deprecation") @Configuration @EnableOAuth2Sso public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated().and().csrf().disable(); } }
TestController.java
package com.xxx.web; import java.util.Arrays; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @GetMapping("/hello") public String hello() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); return authentication.getName()+Arrays.toString(authentication.getAuthorities().toArray()); } }
App.java
package com.xxx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main( String[] args ){ SpringApplication.run(App.class, args); } }
application.yaml
server: port: 8000 servlet: session: cookie: name: s1 security: oauth2: client: client-id: client client-secret: secret user-authorization-uri: http://localhost:8080/oauth/authorize access-token-uri: http://localhost:8080/oauth/token resource: user-info-uri: http://localhost:8080/api/test/user
以上都是代碼部分,下面主要是測試,測試過程很簡單,就是我們啟動兩個服務,打開瀏覽器訪問client-1的http://localhost:8000/hello接口,這時候因為需要登錄,會跳轉到auth-server服務的http://localhost:8080/login,登錄成功,會接著訪問授權接口,授權成功,會跳轉到http://localhost:8000/login,然后跳轉到http://localhost:8000/hello,貌似很復雜,我們先看看效果:
值得注意的是,如圖所示的2、3順序,在這個結果頁面是這樣的,但是在登錄頁面并不是這樣,而是先3后2:
可以這么解釋:client-1的接口http://localhost:8000/hello需要權限才能訪問,這時候,需要登錄自己的系統(tǒng)http://localhost:8000/login,而自己的系統(tǒng)支持oauth2,他通過封裝了client_id,response_type,redirect_uri,state等參數(shù)的授權碼模式請求接口,向auth-server服務發(fā)起授權請求http://localhost:8080/oauth/authorize?client_id=client&redirect_uri=http://localhost:8000/login&response_type=code&state=PphcA2,請求會跳轉auth-server的登錄頁面 http://localhost:8080/login。
這里因為使用了單點登錄,先從client-1跳轉到了auth-server,最后拿到了code之后,跳回了client-1,訪問成功。而頁面上顯示的內容并不是一開始就是這樣子的,他會先跳轉auth-server登錄頁面:
以上代碼有了,結果也驗證了,但是個人還是不是很了解這個登錄授權的原理和過程,也是在學習中,這個所謂的單點登陸,在代碼上就用了一個@EnableOAuth2Sso注解在client-1項目的SecurityConfiguration類上,該類也是繼承自WebSecurityConfigurerAdapter類,然后覆蓋了configure(HttpSecurity http)方法。
到此這篇關于springboot oauth2實現(xiàn)單點登錄實例的文章就介紹到這了,更多相關springboot oauth2單點登錄內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- SpringBoot3.X配置OAuth的代碼實踐
- SpringBoot的Security和OAuth2的使用示例小結
- 使用Springboot實現(xiàn)OAuth服務的示例詳解
- SpringBoot淺析安全管理之OAuth2框架
- springboot集成springsecurity 使用OAUTH2做權限管理的教程
- 基于SpringBoot整合oauth2實現(xiàn)token認證
- springboot2.x實現(xiàn)oauth2授權碼登陸的方法
- 詳解Springboot Oauth2 Server搭建Oauth2認證服務
- 使用Springboot搭建OAuth2.0 Server的方法示例
- SpringBoot集成OAuth2.0的實現(xiàn)示例
相關文章
Java實現(xiàn)順時針輸出螺旋二維數(shù)組的方法示例
這篇文章主要介紹了利用Java如何實現(xiàn)順時針輸出螺旋二維數(shù)組的方法示例,文中給出了詳細的示例代碼和注釋,相信對大家具有一定的參考價值,有需要的朋友們下面來一起看看吧。2017-02-02關于eclipse安裝spring插件報錯An error occurred while collecting item
這篇文章主要介紹了關于eclipse安裝spring插件報錯An error occurred while collecting items to be installed...解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08java實現(xiàn)操作系統(tǒng)中的最佳置換Optimal算法
這篇文章主要介紹了java實現(xiàn)操作系統(tǒng)中的最佳置換Optimal算法 ,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-02-02springboot項目中jackson-序列化-處理 NULL教程
這篇文章主要介紹了springboot項目中jackson-序列化-處理 NULL教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10