プログラムの事とか

お約束ですが「掲載内容は私個人の見解です」

Azure FunctionsでオレオレOAuth

いまさらですがFunctionsはじめました

de:codeだったりネットだったりから情報は収集していましたが実際に作ったことは今までなかったんですが

Functionsすごい、文明開化!!

ということでFunctionsを実務に使おうということになったわけで、認証も必要になるわけなんですが

Basic認証はだめ、なんかだめ

というお上の一言でOAuth認証を入れる羽目になりました

Azure Functionsで認証したかったらEasy Authが楽らしいですね。 ググるとたくさん出てくるんですがAzure ADなんて使えませんしサードパーティーなんてもってのほかです。 認証情報は自分で管理するんです (しろめ)

OAuthやるよ、トークンはJWTだよ

愚痴っぽくだらだら書きましたが、サンプルつくりました

github.com

HttpトリガーのFunctionsが二つ、JWTトークン作ってみるクラスが一つしか入っていないません。トークンは要求すればだれでももらえます

http://localhost:7071/api/tokenトークンを取得

http://localhost:7071/api/helloトークンを見て返す値を変える

というものです

JWTを使うためにNuGetからSystem.IdentityModel.Tokens.Jwtを入れていますが、5.1.5より新しいのを入れるとアセンブリのロードに失敗するらしいので5.1.5を使ってます(解決策は面倒なので調べない)

試す

curlで実際に試してみます

まずは認証無しでhello

curl -i http://localhost:7071/api/hello
HTTP/1.1 401 Unauthorized
Date: Fri, 22 Jun 2018 10:20:15 GMT
Server: Kestrel
Content-Length: 0

Unauthorized返してますね

ということでトークン取得

curl -F user=user -F pass=pass -i http://localhost:7071/api/token
HTTP/1.1 200 OK
Date: Fri, 22 Jun 2018 10:21:12 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked

{"Token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJ1c2VyIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvc2lkIjoidXNlciIsInVuaXF1ZV9uYW1lIjoidXNlciIsIm5iZiI6MTUyOTY2Mjg3MSwiZXhwIjoxNTI5NjYyODgxLCJpYXQiOjE1Mjk2NjI4NzEsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0LyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0LyJ9.rsA2178VEBo28HrM3UeEZxU76LPrBDmSZcoIHkfZe50","ExpirationDate":"2018-06-22T10:21:21Z"}

トークンもらえたのでこれを使います

curl -H "Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJ1c2VyIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvc2lkIjoidXNlciIsInVuaXF1ZV9uYW1lIjoidXNlciIsIm5iZiI6MTUyOTY2Mjg3MSwiZXhwIjoxNTI5NjYyODgxLCJpYXQiOjE1Mjk2NjI4NzEsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0LyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0LyJ9.rsA2178VEBo28HrM3UeEZxU76LPrBDmSZcoIHkfZe50" -i http://localhost:7071/api/hello
HTTP/1.1 200 OK
Date: Fri, 22 Jun 2018 10:22:14 GMT
Content-Type: text/plain; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked

Hello user

200が返ってきました!

見よう見まねで作ったわけですがこれでいいのかな?(そもそもOAuthがちゃんとわかっているのか怪しい)

突っ込み等々ありましたら是非指摘ください

.NET でディレクトリの削除が失敗したりしなかったりする

小ネタ

Windows 10 Pro 1803、.NET Framework 4.7.2 でうごかしてます

準備

Visual Studioで新規のコンソールアプリを作って

class Program
{
    static void Main(string[] args)
    {
        Directory.Delete(@"F:\Test", true);
    }
}

完成

FドライブはSEAGATE ST2000DM006がそのまま割り当てられていて

Testフォルダ内にはいろんなフォルダやファイルが合計100MBくらいはいっています

実行!

f:id:puni-o:20180608170814j:plain

空じゃないと言われたので見てみました

f:id:puni-o:20180608170852j:plain

このフォルダーは空です。

これ毎回失敗するわけじゃないんですが失敗しないと思い込んでいると私のように痛い目をみます

ということでググりました

でてきました

stackoverflow.com

安定のstackoverflow先生、さすがです

結構前の情報なのでいろんな環境で起きるんですかね?どうなんですかね?

そこにおすすめの解決法もありましたよ

static void Main(string[] args)
{
    try
    {
        Directory.Delete(@"F:\Test", true);
    }
    catch (IOException)
    {
        Thread.Sleep(0);
        Directory.Delete(@"F:\Test", true);
    }
}

ディレクトリの一つ上のディレクトリをとる

ネタにもなれないような小ネタですが

そのものずばりなメソッドが無いかナーとググってみたんですが、バックスラッシュ探して文字列操作ってのが上位に出てきてそういものなのかな?と思って自作

public static string GetParentDirectory(string path)   // pathはファイルでもディレクトリでも可
{
    if (path.EndsWith(Path.DirectorySeparatorChar.ToString())) path = path.Substring(0, path.Length - 1);
    return Path.GetDirectoryName(path);
}

バックスラッシュの決め打ちが気持ち悪いのでPath.DirectorySeparatorChar

一つ上のディレクトリはPath.GetDirectoryNameメソッドで

一行目はpathの最後がセパレーター(バックスラッシュ)の場合にPath.GetDirectoryNameが私の望むものを返してくれないのでそのために入れてます(AppDomain.CurrentDomain.BaseDirectoryなどは最後にセパレーターがついて返ってくるんですよね)

異常値チェックしてないのでその辺は雰囲気で

どーでしょう?