Oauth2.0搭建开放平台接口
?
開放平臺
類似qq互聯、微信開放平臺和螞蟻金服開放平臺等,可以實現qq聯合登陸、微信掃碼登陸等。在大型公司中,公司旗下的分公司等相互通訊也可以采用開放平臺形式對接口進行授權使用。
?
?
Oauth
一個開放標準,允許用戶授權第三方網站訪問他們存儲在另外的服務提供者上的信息,而不需要將用戶名和密碼提供給第三方網站或分析他們數據的所有內容。
Oauth2.0相比1.0,其認證流程更簡單和安全。
需要依賴springsecurity。
有四種授權模式
-
密碼模式(resource owner password credentials)
-
授權碼模式(authorization code)
-
簡化模式(implicit)
-
客戶端模式(client credentials)
其中密碼模式和授權碼模式最常用。
?
授權碼模式認證和授權過程:
1.第三方網站向服務商請求一個臨時令牌。
2.服務商驗證第三方網站的身份后,授予一個臨時令牌。
3.第三方網站獲取臨時令牌后,將用戶導向至服務商的授權頁面請求用戶授權,然后這個過程中將臨時令牌和第三方網站的回調地址發送給服務商。
4.用戶在服務商的授權頁面上輸入自己的用戶名和密碼,授權第三方網站訪問所相應的資源。
5.授權成功后,服務商會將用戶導向第三方網站的回調地址。
6.第三方網站根據臨時令牌從服務商獲取訪問令牌。
7.服務商根據令牌和用戶的授權情況授予第三方網站訪問令牌。
8.第三方網站使用獲取到的訪問令牌訪問存放在服務商的對應的用戶資源。
?
?
諸如qq互聯和微信開放平臺等,獲取用戶相關信息的步驟通常如下:
1.生成授權鏈接,獲取授權碼code。
2.使用授權碼獲取accessToken。
3.使用accessToken獲取openid。
4.使用openid獲取用戶信息。
?
?
?
實踐
?
創建Oauth數據庫表,以下是我備份數據庫的sql語句
-- ---------------------------- -- Table structure for clientdetails -- ---------------------------- CREATE TABLE `clientdetails` (`appId` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NOT NULL,`resourceIds` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`appSecret` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`scope` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`grantTypes` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`redirectUrl` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`authorities` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`access_token_validity` int(11) NULL DEFAULT NULL,`refresh_token_validity` int(11) NULL DEFAULT NULL,`additionalInformation` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`autoApproveScopes` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,PRIMARY KEY (`appId`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_zh_0900_as_cs ROW_FORMAT = Dynamic;-- ---------------------------- -- Table structure for oauth_access_token -- ---------------------------- CREATE TABLE `oauth_access_token` (`token_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`token` blob NULL,`authentication_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NOT NULL,`user_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`client_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`authentication` blob NULL,`refresh_token` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,PRIMARY KEY (`authentication_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_zh_0900_as_cs ROW_FORMAT = Dynamic;-- ---------------------------- -- Table structure for oauth_approvals -- ---------------------------- CREATE TABLE `oauth_approvals` (`userId` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`clientId` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`scope` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`status` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`expiresAt` timestamp(0) NULL DEFAULT NULL,`lastModifiedAt` timestamp(0) NULL DEFAULT NULL ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_zh_0900_as_cs ROW_FORMAT = Dynamic;-- ---------------------------- -- Table structure for oauth_client_details -- ---------------------------- CREATE TABLE `oauth_client_details` (`client_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NOT NULL,`resource_ids` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`client_secret` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`scope` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`authorized_grant_types` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`web_server_redirect_uri` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`authorities` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`access_token_validity` int(11) NULL DEFAULT NULL,`refresh_token_validity` int(11) NULL DEFAULT NULL,`additional_information` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`autoapprove` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,PRIMARY KEY (`client_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_zh_0900_as_cs ROW_FORMAT = Dynamic;-- ---------------------------- -- Table structure for oauth_client_token -- ---------------------------- CREATE TABLE `oauth_client_token` (`token_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`token` blob NULL,`authentication_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NOT NULL,`user_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`client_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,PRIMARY KEY (`authentication_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_zh_0900_as_cs ROW_FORMAT = Dynamic;-- ---------------------------- -- Table structure for oauth_code -- ---------------------------- CREATE TABLE `oauth_code` (`code` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`authentication` blob NULL ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_zh_0900_as_cs ROW_FORMAT = Dynamic;-- ---------------------------- -- Table structure for oauth_refresh_token -- ---------------------------- CREATE TABLE `oauth_refresh_token` (`token_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_zh_0900_as_cs NULL DEFAULT NULL,`token` blob NULL,`authentication` blob NULL ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_zh_0900_as_cs ROW_FORMAT = Dynamic;?
?
創建授權中心項目。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.8.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>oauthtest</artifactId><version>0.0.1-SNAPSHOT</version><name>oauthtest</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- SpringBoot整合Web組件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- springboot整合freemarker --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!-->spring-boot 整合security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- spring-cloud-starter-oauth2 --><dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>?
?
application.yml
spring:datasource:hikari:connection-test-query: SELECT 1minimum-idle: 1maximum-pool-size: 5pool-name: dbcp1driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/oauth?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456?
?
創建security配置文件
package com.example.oauthtest;import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/*** security配置文件*/ @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//配置攔截請求為所有請求,授權模式為httpBasichttp.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();} }?
?
創建授權中心配置文件
package com.example.oauthtest;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 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; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; import org.springframework.security.provisioning.InMemoryUserDetailsManager;import javax.sql.DataSource;/*** 授權中心配置文件*/ @Configuration @EnableAuthorizationServer //開啟認證授權中心 public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate DataSource dataSource;@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients(); //允許表單登陸}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {//添加授權用戶,類似在qq互聯創建一個賬號,然后會被分配一個client_id和secret//一般會用專門的項目或接口用來給用戶創建賬號,這里為了方便,直接添加測試賬號clients.jdbc(dataSource) //設置數據源.withClient("client1") //設置client_id.secret(new BCryptPasswordEncoder().encode("123456")) //設置client_secret.authorizedGrantTypes("password", "refresh_token", "authorization_code") //允許授權范圍.redirectUris("http://www.baidu.com") //回調地址.authorities("ROLE_ADMIN") //客戶端可以使用的權限.scopes("all") //范圍 暫不知道用處.accessTokenValiditySeconds(7200) //token過期時間.refreshTokenValiditySeconds(7200); //刷新token的有效時間}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager()).userDetailsService(userDetailService());//不設置userDetailService的話刷新token會報錯}@Beanpublic AuthenticationManager authenticationManager() {AuthenticationManager authenticationManager = new AuthenticationManager() {@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {return daoAuthenticationProvider().authenticate(authentication);}};return authenticationManager;}@Beanpublic AuthenticationProvider daoAuthenticationProvider() {DaoAuthenticationProvider provider = new DaoAuthenticationProvider();provider.setUserDetailsService(userDetailService());provider.setHideUserNotFoundExceptions(false);provider.setPasswordEncoder(passwordEncoder());return provider;}@Beanpublic PasswordEncoder passwordEncoder() {//加密方式return new BCryptPasswordEncoder();}@Beanpublic UserDetailsService userDetailService() {//創建security用戶InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();userDetailsManager.createUser(User.withUsername("user1").password(new BCryptPasswordEncoder().encode("123456")).authorities("ROLE_USER").build());return userDetailsManager;}@Beanpublic TokenStore tokenStore() {//return new InMemoryTokenStore(); 使用內存中的token storereturn new JdbcTokenStore(dataSource); //使用Jdbctoken store,即將token存進數據庫} }?
?
springboot入口類
package com.example.oauthtest;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class OauthtestApplication {public static void main(String[] args) {SpringApplication.run(OauthtestApplication.class, args);}}?
?
啟動springboot入口類
用postman訪問接口
?
在token過期前10分鐘左右需要進行刷新token,否則授權就失效了。
一般refreshToken的過期時間需要設置長一點,否則refreshToken過期了就不能用來刷新了~
以上是密碼模式。
?
?
接下來使用授權碼模式。
1.獲取授權碼
打開瀏覽器,輸入http://localhost:8080/oauth/authorize?response_type=code&client_id=client1&redirect_uri=http://www.baidu.com?
?
如果彈出登陸框的話,就用賬號user1,密碼123456登陸
?
如果出現以下頁面
就選擇Approve,然后點擊按鈕,意思是同意授權
?
然后網頁會跳轉到百度,因為百度是我們設置的回調地址
可以發現地址中后邊帶著一個code參數,這個就是我們獲取到的授權碼
?
?
2.獲取token
使用postman
?
?
可以發現用授權碼模式獲取到的token跟密碼模式獲取的token一樣,說明在兩種授權模式同時使用的情況下,獲取到的token是一樣的,并不會產生覆蓋或者不一致的情況。
授權模式刷新token的方式和密碼模式一樣。
?
?
?
?
?
創建資源項目
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.8.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>oauthresource</artifactId><version>0.0.1-SNAPSHOT</version><name>oauthresource</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- SpringBoot整合Web組件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- springboot整合freemarker --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!-->spring-boot 整合security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>?
?
?
配置文件application.yml
server:port: 8081logging:level:org.springframework.security: DEBUG security:oauth2:resource:token-info-uri: http://localhost:8080/oauth/check_tokenprefer-token-info: trueclient:access-token-uri: http://localhost:8080/oauth/tokenuser-authorization-uri: http://localhost:8080/oauth/authorizeclient-id: client1client-secret: 123456?
?
創建配置文件
package com.example.oauthresource;import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;@Configuration @EnableResourceServer //開啟資源服務 public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {@Overridepublic void configure(HttpSecurity http) throws Exception {//攔截請求,被攔截到的需要驗證token,一般在網關里面做,開放接口和內部接口一般要獨立出來,這樣就不會一起攔截到了。http.authorizeRequests().antMatchers("/resource/**").authenticated();} }?
?
?
創建controller
?
package com.example.oauthresource;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/resource") public class ResourceController {@RequestMapping("/getResource")public String getResource(){return "訪問到了資源文件";} }?
?
?
springboot入口類
package com.example.oauthresource;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;@SpringBootApplication public class OauthresourceApplication {public static void main(String[] args) {SpringApplication.run(OauthresourceApplication.class, args);}}?
?
?
啟動springboot入口類
使用postman訪問接口http://127.0.0.1:8081/resource/getResource
發現報了一個沒有權限的錯誤
?
在請求頭加上token再次請求
發現成功訪問到了接口。
需要注意的是,token前邊需要加上字符串bearer,與token值之間帶一個空格。
?
?
?
以上項目很多需要靈活設置的東西都是寫死的,等有空研究一下再換成活的。
總結
以上是生活随笔為你收集整理的Oauth2.0搭建开放平台接口的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fni matlab,使用Matlab求
- 下一篇: 职场达人必备!100本管理类的书籍