本帖最后由 David.Zhong 于 2023-5-25 14:05 编辑
支持 OAuth 2.0 认证
这个功能,其实在活字格的上一个版本,发布http请求命令的时候,我专门讲过一些这个概念
当活字格的应用和其他系统的应用交互数据的时候,其实无非就是以下两种情况:
- 活字格应用总第三方系统中获取数据(比如活字格获取淘宝,京东的数据)
- 第三方系统从活字格应用获取数据(比如使用活字格开发了一个MES,现在有其他人希望获取这个活字格MES系统的数据)
我们之前推出了发送HTTP请求命令以后,在加上这次对这个命令的升级支持修改header以后,咱们就能解决情况1的整体的场景了
因为说白了,其实OAuth就是来回使用http请求交互几次数据,然后大家互相就认识并认可对方了
这种情况下,这个OAuth需要的在人家第三方的系统中支持,咱才能使用
但是,其他系统想要调用活字格的数据,此时就需要活字格支持OAuth了,所以上次我说过,在此种情况下,活字格还差点东西
在学习活字格的OAuth之前,如果大家对OAuth还不是很了解,建议大家可以先看看这里,磨刀不误砍柴工
什么是OAuth 2.0:http://www.ruanyifeng.com/blog/2019/04/oauth_design.html
OAuth 2.0的四种方式:https://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
活字格的OAuth 2.0使用的凭证式(client_credentials)和密码式(password)两种。
本次活字格7.0中,我们就让活字格支持了OAuth,别的系统就可以更好的调用数据了,这样也更加的安全,那么怎么使用这个功能呢?
授权设定登录管理门户网站,然后单击设置→Web安全性页面,如下所示,管理员可以为每个第三部分配置客户端标识符和密码。 如何配置第三方客户端授权设置
单击“添加客户端授权”按钮,然后编辑授权类型,允许范围和令牌生存期等。 选项说明
客户名称客户端显示名称(用于记录)。 客户端标识符客户端的唯一ID。 客户端密钥客户机密-仅与需要机密的流有关。 授权方式指定允许的授予类型(现在我们支持ResourceOwner,ClientCredentials的合法组合)。 API作用域指定允许客户端请求的api作用域。如果要访问应用程序的服务器端命令,则可以使用应用程序名称作为其api范围;如果您要访问与用户相关的api(例如AddUsers),则可以使用“ FGC_UserApis ”作为api作用域。 令牌生命周期访问令牌的生存时间(以秒为单位)(默认为7200秒/ 2小时)。并且有5分钟的时间偏移(以解决客户端和服务器时间可能不同步的问题)。 支持刷新令牌
获取或设置一个值,该值指示是否[允许离线访问]。默认为false。 ClientCredentials授予类型不支持刷新令牌。 如何在第三部分中添加用户
如下配置客户端授权,并支持password和client_credentials授予类型,并允许FGC_UserAPIs作用域,以便具有此客户端ID和客户端密码的第三部分可以添加用户。 这里列出了PostMan和C#客户端程序访问UserAPI的两种方式。
PostMan 1.添加没有OAuth令牌的用户。(状态:401未经授权)
凭证式
这是client_credentials授予类型请求参数列表:
参数
| | | client_id | 82aed47e6b43c00962e89cc21a2d15b0 | 客户端授权设置中的客户端标识符 | client_secret | 191f6cc9b163ce617c61bd655d01e125 | 客户端授权设置中的客户端机密 | scope(可选参数,以服务端第三方授权设置为准) | FGC_UserAPI | API范围 | grant_type | client_credentials | 授权类型 |
结果
2.添加具有访问令牌的用户。(状态:200 OK) 在步骤2中复制“ access_token”值,并在“ access_token”值之前插入“ Bearer”,然后按如下所示将其添加到键“ Authorization”的值中,并再次请求添加用户。 这是结果
密码式 这是密码授予类型请求参数列表:
参数
| | | client_id | 82aed47e6b43c00962e89cc21a2d15b0 | 客户端授权设置中的客户端标识符 | client_secret | 191f6cc9b163ce617c61bd655d01e125 | 客户端授权设置中的客户端机密 | scope(可选参数,以服务端第三方授权设置为准) | FGC_UserAPIs | API范围 | grant_type | password | 授权类型 | userName | 行政人员 |
| password | 123456 |
|
这是结果 2.添加具有访问令牌的用户。(状态:200 OK) 在步骤4中复制“ access_token”值,并在“ access_token”值之前插入“ Bearer”,然后按如下所示将其添加到键“ Authorization”的值中,并再次请求添加用户。
这是结果
Refresh_token 令牌的有效期到了,如果让用户重新走一遍上面的流程,再申请一个新的令牌,很可能体验不好,而且也没有必要。OAuth 2.0 允许用户自动更新令牌。 具体方法是,活字格网站颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。
1.在密码授予类型中获取带有刷新令牌的访问令牌。 首先,当您第一次获得密码令牌时,可以按以下方式将offline_access添加到范围中,以便也将返回刷新令牌,多个范围之间用空格分隔; 然后,您可以按照以下方式获得带有刷新令牌的新访问令牌,以便可以添加具有新访问令牌的用户,而无需用户名和密码; C#客户端程序
1.添加没有OAuth令牌的用户。 (状态:未经授权的401)
- var client = new HttpClient();
- var param = new UserInfosParam()
- {
- UserInfos = new List<UserInfo>()
- {
- new UserInfo()
- {
- UserName = "ClientUser",
- FullName = "ClientUser",
- Password = "123456",
- Email = "ClientUser@email.com"
- }
- }
- };
-
- var response = await client.PostAsync("http://xa-dd3-bks:22345/UserService/Manager/User/AddUsers", new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(param), Encoding.UTF8, "application/json"));
-
- Console.WriteLine((int)response.StatusCode);
- Console.WriteLine(response.StatusCode);
复制代码 这是结果
这是使用的IdentityModel程序集。 - var client = new HttpClient();
-
- var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
- {
- Address = "http://xa-dd3-bks:22345/UserService/",
- Policy =
- {
- RequireHttps = false,
- ValidateIssuerName = false,
- ValidateEndpoints = false
- }
- });
- if (disco.IsError)
- {
- throw new Exception(disco.Error);
- }
-
- // request token
- var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest()
- {
- Address = disco.TokenEndpoint,
- ClientId = "82aed47e6b43c00962e89cc21a2d15b0",
- ClientSecret = "191f6cc9b163ce617c61bd655d01e125",
- Scope = "FGC_UserAPIs"
- });
-
- Console.WriteLine(tokenResponse.Json);
复制代码这是结果 3.使用OAuth令牌添加用户。(状态:200 OK) - var client = new HttpClient();
-
- client.SetBearerToken("eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc3OEREQzkxOTE5ODhFREZEOEZFNkRERUYyNTNCNjkyIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MDc3NTkyMTUsImV4cCI6MTYwNzc2NjQxNSwiaXNzIjoiaHR0cDovL3hhLWRkMy1ia3M6MjIzNDUvdXNlcnNlcnZpY2UiLCJhdWQiOiJGR0NfVXNlckFQSXMiLCJjbGllbnRfaWQiOiI4MmFlZDQ3ZTZiNDNjMDA5NjJlODljYzIxYTJkMTViMCIsImp0aSI6IjdEQjExRDg1OUQ4Mzk0MDE3QTI5QjM3QzdCQkVDMjIyIiwiaWF0IjoxNjA3NzU5MjE1LCJzY29wZSI6WyJGR0NfVXNlckFQSXMiXX0.SQw6z7NlGQNgNsyWwy-YOosZeKl9eeh3jVvsTcimfK5DIGV8KmmAVwAVhEPwa82Rp_UoIPbqdFv3QH8J7r2Sa3u7vGT4OK35XuZiZUNL8nNhfxlDjMvKyfz1lZ0NQg3YBMS5-AU6jUN1rfdXj8TUY0-woLnLlyor_404BbEIDOuw4Xk_qEeFu0Ti6KVUThAr0FLEJKUJoHr5lYWhWRkmK0lqftqL-FrkURtC_S4ONN5IjJPzJwtT_YkgzBSb-NXf05ZSAK9VWrvqUWlfmn0plTr9pI3MxcRyxw8-sowOJ4CMIAZOP_DLZM7J1fHtNQHFAX-VnGLi_7LGgMaNPjDq2w");
-
- var param = new UserInfosParam()
- {
- UserInfos = new List<UserInfo>()
- {
- new UserInfo()
- {
- UserName = "ClientUser",
- FullName = "ClientUser",
- Password = "123456",
- Email = "ClientUser@email.com"
- }
- }
- };
-
- var response = await client.PostAsync("http://xa-dd3-bks:22345/UserService/Manager/User/AddUsers", new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(param), Encoding.UTF8, "application/json"));
-
- Console.WriteLine((int)response.StatusCode);
- Console.WriteLine(response.StatusCode);
复制代码这是结果
这是使用的IdentityModel程序集。 - var client = new HttpClient();
-
- var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
- {
- Address = "http://xa-dd3-bks:22345/UserService/",
- Policy =
- {
- RequireHttps = false,
- ValidateIssuerName = false,
- ValidateEndpoints = false
- }
- });
- if (disco.IsError)
- {
- throw new Exception(disco.Error);
- }
-
- // request token
- var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest()
- {
- Address = disco.TokenEndpoint,
- ClientId = "82aed47e6b43c00962e89cc21a2d15b0",
- ClientSecret = "191f6cc9b163ce617c61bd655d01e125",
- Scope = "FGC_UserAPIs",
- UserName = "Administrator",
- Password = "123456"
- });
-
- Console.WriteLine(tokenResponse.Json);
复制代码这是结果 5.添加具有密码令牌的用户。(状态:200 OK) - var client = new HttpClient();
-
- client.SetBearerToken("eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc3OEREQzkxOTE5ODhFREZEOEZFNkRERUYyNTNCNjkyIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MDc3NTk1OTgsImV4cCI6MTYwNzc2Njc5OCwiaXNzIjoiaHR0cDovL3hhLWRkMy1ia3M6MjIzNDUvdXNlcnNlcnZpY2UiLCJhdWQiOiJGR0NfVXNlckFQSXMiLCJjbGllbnRfaWQiOiI4MmFlZDQ3ZTZiNDNjMDA5NjJlODljYzIxYTJkMTViMCIsInN1YiI6IkFkbWluaXN0cmF0b3IiLCJhdXRoX3RpbWUiOjE2MDc3NTk1OTgsImlkcCI6ImxvY2FsIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6IkFkbWluaXN0cmF0b3IiLCJqdGkiOiIzMzc3RDNFOEYwMjQ3ODE4RkI5RTk3QUU0N0MyOTY0NyIsImlhdCI6MTYwNzc1OTU5OCwic2NvcGUiOlsiRkdDX1VzZXJBUElzIl0sImFtciI6WyJVc2VyIl19.FqhPaevvow_JenA4bIexdm7n-lWrBMA771dE5w_uGk6lY1hpjgh1XQZry-84-0Hv6H0blkl0M8suPuVluT1sBLAgRXgGq5r4OJL_WYmkWMEYeJ6cLA0qolKwX2XwV2lHoV_OaXpsUdyOTCUxlUOcJXfYDlNrTzrbzowyIT0KZp3hBGVN1ZXs5Zc7eyfW0X8hG9am_Uc-7fPvc0fBmqL8BUEh1iDkTu8YyHgewTFpQ6WEHO_0JNReZHjuwz1Wz_FrBnu_AjUXo3QrpQ3SowcMte5hJH_zb5QNR_eze84kmFkh_N1RjOp13_MyUSZKGhZYCwj6VeDnY-b5wjzggZ0Qrg");
-
- var param = new UserInfosParam()
- {
- UserInfos = new List<UserInfo>()
- {
- new UserInfo()
- {
- UserName = "ClientUser",
- FullName = "ClientUser",
- Password = "123456",
- Email = "ClientUser@email.com"
- }
- }
- };
-
- var response = await client.PostAsync("http://xa-dd3-bks:22345/UserService/Manager/User/AddUsers", new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(param), Encoding.UTF8, "application/json"));
-
- Console.WriteLine((int)response.StatusCode);
- Console.WriteLine(response.StatusCode);
复制代码这是结果 6.在密码授予类型中获取带有刷新令牌的访问令牌。
首先,当您第一次获得密码令牌时,可以按以下方式将offline_access添加到范围中,以便也将返回刷新令牌,多个范围之间用空格分隔;
- // request token
- var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest()
- {
- Address = disco.TokenEndpoint,
- ClientId = "82aed47e6b43c00962e89cc21a2d15b0",
- ClientSecret = "191f6cc9b163ce617c61bd655d01e125",
- Scope = "FGC_UserAPIs offline_access",
- UserName = "Administrator",
- Password = "123456"
- });
复制代码这是结果 然后,您可以按照以下方式获得带有刷新令牌的新访问令牌,以便可以添加具有新访问令牌的用户,而无需用户名和密码; - var client = new HttpClient();
-
- var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
- {
- Address = "http://xa-dd3-bks:22345/UserService/",
- Policy =
- {
- RequireHttps = false,
- ValidateIssuerName = false,
- ValidateEndpoints = false
- }
- });
- if (disco.IsError)
- {
- throw new Exception(disco.Error);
- }
-
- // request token
- var tokenResponse = await client.RequestRefreshTokenAsync(new RefreshTokenRequest()
- {
- Address = disco.TokenEndpoint,
- ClientId = "82aed47e6b43c00962e89cc21a2d15b0",
- ClientSecret = "191f6cc9b163ce617c61bd655d01e125",
- Scope = "FGC_UserAPIs offline_access",
- RefreshToken = "AE513A86E494F70C93347F630ECD475690B354B8D08006636708A01DB8DC12E8"
- });
-
- Console.WriteLine(tokenResponse.Json);
复制代码这是结果
看完以后,不知道你是不是这个感觉?? 没关系,你只要支持一件事,现在活字格7.0,前面的两种情况都支持了;数据可以自由,安全的在活字格和第三方系统中来回游走了~~
当然,会写代码了解什么是OAuth是什么的同学,应该看完了以后更加确定我上面说的2种情况活字格都是支持的了 没错,不经意间活字格更加强大了~
|