LoginSignup
6
10

More than 5 years have passed since last update.

ログイン処理を行うOWINミドルウェアの作成

Posted at

一式を https://github.com/ken200/OwinAuthWithNancy に配置しています。

本件に関連するソースコードは LoginMiddleware.cs と startup.cs に記載しています。

必要パッケージ

  • Microsoft.Owin

  • Microsoft.Owin.Security

  • Microsoft.Owin.Security.Cookies

  • Owin

構成物

ミドルウェア

Microsoft.Owin.OwinMiddlewareクラスを継承して作成するのが無難かと思われます。

KatanaProjectに依存することになるけど、MS製なのでさほど問題にはならないと考えています。

ミドルウェアでの認証関係について、複雑なことは行っていません。読んでもらえればわかるけど、SignInメソッドの「context.Authentication.SignIn(userIdentity);」で認証登録し、その後リダイレクトしています。


//ミドルウェアコードを一部抜粋

public class LoginMiddleware : OwinMiddleware
{
    public LoginMiddleware(...)
        : base(...)
    {
        ...
    }

    public async override Task Invoke(IOwinContext context)
    {
        if(!IsAuthenticated(context))
        {
            await SignIn(context);
            return;
        }

        await Next.Invoke(context);
    }

    ...

    private async Task SignIn(IOwinContext context)
    {
        //ログインユーザー名の取得
        var userName = await _loginOption.UserNameGetter(context);

        if (string.IsNullOrEmpty(userName))
        {
            //レスポンスに書き込み。次ミドルウェアへの伝番は行わない。
            await WriteResponse(context.Response, 401, "invalid parameter.");
            return;
        }

        //ユーザーストアに対象ユーザーが存在するか確認
        var uMng = new MyUserManager();
        var userIdentity = await uMng.CreateAsync(userName);
        if (userIdentity == null)
        {
            await WriteResponse(context.Response, 401, "invalid user.");
            return;
        }

        //認証登録
        context.Authentication.SignIn(userIdentity);

        //リダイレクト
        var q = context.Request.Query[_loginOption.RedirectUrlQueryName];
        var redirectPath = !string.IsNullOrEmpty(q) ? q : _loginOption.DefaultRedirectUrl;
        context.Response.Redirect(redirectPath);
    }

    ...
}

ユーティリティークラス

UseXXXX()な拡張メソッドを定義する。これ経由でミドルウェアを登録する慣わし?

public static class LoginExtentions
{
    public static IAppBuilder UseLogin(this IAppBuilder app, LoginOptions loginOption, LogoutOptions logoutOption)
    {
        return app.Use<LoginMiddleware>(loginOption, logoutOption);
    }
}

Startupクラスでの登録

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        //クッキーベースの認証する際に必要なミドルウェア
        app.UseCookieAuthentication(new CookieAuthenticationOptions() {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie
        });

        //独自認証ミドルウェア
        app.UseLogin(
            new LoginOptions() { 
                LoginUrl = "/login", 
                LoginMethod = "POST", 
                UserNameGetter = async (ctx) => {
                    var form = await ctx.Request.ReadFormAsync();
                    return form.Get("userName");
                },
                DefaultRedirectUrl = "/secure"},
            new LogoutOptions() { 
                LogoutUrl = "/logout", 
                DefaultRedirectUrl = "/" });

        app.UseNancy();
    }
}
6
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
10