LINEWORKS API 2.0 C# で AccessToken を得る方法 [Newtonsoft.Json を使わない版]
NET 5.0 ~ は、「ImportFromPem」というメソッドが備わっているため、LINEWORKS が提供している PEM 形式の private-key をそのまま読み込める。
System.Collections.Generic.Dictionary<string, string> GetAccessToken(System.IO.FileInfo privateKey, string service_account, string client_id, string client_secret, params string[] scopes) { using (var rsa = System.Security.Cryptography.RSA.Create()) { rsa.ImportFromPem(System.IO.File.ReadAllText(privateKey.FullName)); var descriptor = new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor { Issuer = client_id, Claims = new System.Collections.Generic.Dictionary<string, object>() { ["sub"] = service_account }, SigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(new Microsoft.IdentityModel.Tokens.RsaSecurityKey(rsa), "RS256"), IssuedAt = System.DateTime.UtcNow, Expires = System.DateTime.UtcNow.AddMinutes(60), }; var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(); var pv = new System.Collections.Specialized.NameValueCollection() { ["assertion"] = handler.WriteToken(handler.CreateJwtSecurityToken(descriptor)), ["grant_type"] = @"urn:ietf:params:oauth:grant-type:jwt-bearer", ["client_id"] = client_id, ["client_secret"] = client_secret, ["scope"] = string.Join(",", scopes), }; using (var wc = new System.Net.WebClient()) { var resText = System.Text.Encoding.ASCII.GetString(wc.UploadValues(@"https://auth.worksmobile.com/oauth2/v2.0/token", pv)); return System.Text.Json.JsonSerializer.Deserialize<System.Collections.Generic.Dictionary<string, string>>(resText); } } }
※「System.IdentityModel.Tokens.Jwt」を nuget しておくこと
NET Framework ~ 4.8 だと XML 形式の private-key しか読めないので、いったん NET 5.0 ~ を使って XML に変換するプログラムを書いて変換しておく。
void PEM2XML(System.IO.FileInfo pemFile) { using (var rsa = System.Security.Cryptography.RSA.Create()) { rsa.ImportFromPem(File.ReadAllText(pemFile.FullName)); File.WriteAllText(pemFile.FullName + ".xml", rsa.ToXmlString(true)); } }
そのうえで、「ImportFromPem」の代わりに「FromXmlString」を使う。
System.Collections.Generic.Dictionary<string, string> GetAccessToken(System.IO.FileInfo privateKey, string service_account, string client_id, string client_secret, params string[] scopes) { using (var rsa = System.Security.Cryptography.RSA.Create()) { rsa.FromXmlString(System.IO.File.ReadAllText(privateKey.FullName)); var descriptor = new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor { Issuer = client_id, Claims = new System.Collections.Generic.Dictionary<string, object>() { ["sub"] = service_account }, SigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(new Microsoft.IdentityModel.Tokens.RsaSecurityKey(rsa), "RS256"), IssuedAt = System.DateTime.UtcNow, Expires = System.DateTime.UtcNow.AddMinutes(60), }; var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(); var pv = new System.Collections.Specialized.NameValueCollection() { ["assertion"] = handler.WriteToken(handler.CreateJwtSecurityToken(descriptor)), ["grant_type"] = @"urn:ietf:params:oauth:grant-type:jwt-bearer", ["client_id"] = client_id, ["client_secret"] = client_secret, ["scope"] = string.Join(",", scopes), }; using (var wc = new System.Net.WebClient()) { var resText = System.Text.Encoding.ASCII.GetString(wc.UploadValues(@"https://auth.worksmobile.com/oauth2/v2.0/token", pv)); return System.Text.Json.JsonSerializer.Deserialize<System.Collections.Generic.Dictionary<string, string>>(resText); } } }