2019年7月29日月曜日

[C#]LINEWORKS用のJWT認証を行ってメッセージを送る

そのものズバリな記事がなかったので、作成。
C#のLINEのチャットbotの作り方はありますけどLINE WORKSはまだまだ全然ない…
そもそもC#でLINE WORKS作る人少なそう…

①ー1 まずはLINEWORKSとの連携に必要な値の設定
以下の様に値を宣言します。
LINE WORKS Developersで設定した値をセットします。

static int botNo = 9999;
static string apiId = "kfew******Oy";
static string serverId = "afei*******24239e";
static string consumerKey = "WOpe*******elK";
static string privateKey = "-----BEGIN PRIVATE KEY-----MAIEvA******JZhJIZ=-----END PRIVATE KEY-----";

serverId …ServerList(ID固定タイプ)のIDをセット
consumerKey …ServerApiConsumerKeyをセット
privateKey ServerList(ID固定タイプ)の認証キーを1行につなげます。


②ー1 JWT認証を使ってアクセストークンの取得(準備)


Pemキー(privatekey)を.NETで扱うのは難しく、RSAとして使用するには一度xmlに変換しないといけないらしい…これがつらかった。
これを解消する為に、Nugetで「opensslkey」を追加しておきます
(OpensslKey.csというプログラムが出来るだけ)

②ー2 JWT認証を使ってアクセストークンの取得(関数)


OpensslKeyを使って以下の関数を作ります。これでアクセストークンが取得できます。


public string GetAccessToken()
        {
            //JWTトークンの作成=======================================================
            string request_jwt = null;
            //privatekeyRSAとして使用できるように変換
            var pkcs8privatekey = Security.opensslkey.DecodePkcs8PrivateKey(privateKey); 
            var rsa = Security.opensslkey.DecodePrivateKeyInfo(pkcs8privatekey);  
            var key = new Microsoft.IdentityModel.Tokens.RsaSecurityKey(rsa);
            // トークン操作用のクラスを用意
            var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
            // 署名情報クラスを生成
            var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(key, "RS256");
            var descriptor = new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor
            {
                Issuer = serverId,
                SigningCredentials = credentials,
                IssuedAt = DateTime.UtcNow,
                Expires = (DateTime.UtcNow).AddMinutes(10),
            };
            // トークンの生成
            var token = handler.CreateJwtSecurityToken(descriptor);
            // トークンの文字列表現を取得
            var tokenString = handler.WriteToken(token);


            //アクセストークンの取得=======================================================
            //認証URL
            string TOKEN_ENDPOINT = @"https://auth.worksmobile.com/b/" + apiId + "/server/token";
            var client = new WebClient();
            client.Encoding = Encoding.UTF8;
            var content = new NameValueCollection();
            request_jwt = tokenString;
            content["assertion"] = request_jwt;
            content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
            string response = Encoding.UTF8.GetString(client.UploadValues(TOKEN_ENDPOINT, "POST", content));
            var result = JsonConvert.DeserializeObject<Token>(response);           
            return result.AccessToken;
        }






③ー1 送信してみる
content(内容)は省きますが、以下の様に行えば実際に送信できます。


//(obj_contentは各自でModelを作って作成)
 string jsonRequest = JsonConvert.SerializeObject(obj_content);

 StringContent content = new StringContent(jsonRequest);
 content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

 HttpClient client = new HttpClient(); 
 var url = "https://apis.worksmobile.com/"apiId + "/message/sendMessage/v2";
 var token = GetAccessToken();
 var request = new HttpRequestMessage(HttpMethod.Post, url);
 request.Headers.Add("ContentType", "application/json");
 request.Headers.Add("Authorization", "Bearer " + token);
 request.Headers.Add(@"consumerKey", @""consumerKey );

 request.Content = content;
 var response = await client.SendAsync(request);

 //string responseContent = await response.Content.ReadAsStringAsync();




1 件のコメント:

  1. はじめまして。
    C#でのトークンが欲しくて参考にさせてもらいましたが、client.UploadValuesでタイムアウトとなってしまいます。何が原因なのかご教授いただけないでしょうか?

    返信削除