我将从cookieauthenticationmiddleware中间件的使用,来讲述cookie认证是如何实现的

1、系统是如何调用cookieauthenticationmiddleware的

在web.config的appsettings里添加<add key=”owin:appstartup” value=”你自己的config类:namespace.class” >

public class identityconfig
{
    public void configuration(iappbuilder app)
    {
       // 默认使用cookieauthenticationmiddleware
       app.usecookieauthentication(new cookieauthenticationoptions
            {
                authenticationtype = defaultauthenticationtypes.applicationcookie,
                loginpath = new pathstring("/account/login")
            });
    }
}

在cookieauthenticationextensions里定义了默认的cookieauthentication中间件

public static iappbuilder usecookieauthentication(this iappbuilder app, cookieauthenticationoptions options, pipelinestage stage)
        {
            if (app == null)
            {
                throw new argumentnullexception("app");
            }
            // 默认中间件
            app.use(typeof(cookieauthenticationmiddleware), app, options);
            app.usestagemarker(stage);
            return app;
        }

2、主要class说明

cookieauthenticationmiddleware:项目使用时调用的验证中间件类,下面简称 【cookieauth中间件类】

authenticationmiddleware<cookieauthenticationoptions>:cookieauthenticationmiddleware的父类,下面简称 【auth中间件类】

—下面说的是重点,实际的工作处理者——–

cookieauthenticationhandler:【cookieauth处理类】

authenticationhandler<toptions>:泛型抽象类,主要有个方法initialize。是cookieauthenticationhandler的父类,下面简称 【auth处理子类】。

authenticationhandler:抽象类,主要有baseinitializeasync和teardownasync方法,是authenticationhandler<toptions>的父类,下面简称 【auth处理基类】。

3、代码功能说明

public abstract class authenticationmiddleware<toptions> : owinmiddleware where toptions : authenticationoptions
{
    protected authenticationmiddleware(owinmiddleware next, toptions options)  : base(next)
    {
            if (options == null)
            {
                throw new argumentnullexception("options");
            }

            options = options;
    }

    public toptions options { get; set; }

    // 具体的执行流程很简单,分为创建,初始化,下一个中间件执行,卸载
    public override async task invoke(iowincontext context)
    {
        //获取处理者,【cookieauth处理类】
        authenticationhandler<toptions> handler = createhandler();
        //初始化,会调用【auth处理基类】的baseinitializeasync,具体查看---initialize说明---
        await handler.initialize(options, context);
        if (!await handler.invokeasync())//默认返回false
        {
            //调用下一个中间件,比方说调用mvc中间件
            await next.invoke(context);
        }
        // 最后执行,会调用【auth处理基类】的teardownasync,具体说明查看---teardown说明---
        await handler.teardownasync();
    }

    protected abstract authenticationhandler<toptions> createhandler();
}

—initialize说明—
初始化的时候,将获取已有的ticket,供后续的中间件使用
将调用【auth处理基类】的baseinitializeasync来完成初始化

 protected async task baseinitializeasync(authenticationoptions options, iowincontext context)
        {
            _baseoptions = options;
            context = context;
            helper = new securityhelper(context);
            requestpathbase = request.pathbase;

            _registration = request.registerauthenticationhandler(this);
           // 设置响应事件,在teardown之后会执行
            response.onsendingheaders(onsendingheadercallback, this);

            await initializecoreasync();
            // 主动模式时执行
            if (baseoptions.authenticationmode == authenticationmode.active)
            {
                // 根据cookie得到ticket,判断是否需要renew,后续的中间件可以获取identity信息
                authenticationticket ticket = await authenticateasync();
                if (ticket != null && ticket.identity != null)
                {
                    // 将identity添加到context.request.user里
                    helper.adduseridentity(ticket.identity);
                }
            }
        }

—teardown说明—
就是判断是否是登录,注销,renew,然后处理
登录:制作ticket写入cookie
注销:删除cookie
renew(剩余时长<使用时长):重新生成cookie的有效期

internal async task teardownasync()
        {
            // 申请响应
            // 判断是否是登录(iauthenticationmanager.signin),注销(iauthenticationmanager.signout),renew(_shouldrenew标志),然后处理
            await applyresponseasync();
            // 默认返回null
            await teardowncoreasync();
            // request[key:constants.securityauthenticate],注销authenticationhandler,恢复成registerauthenticationhandler之前的状态
            request.unregisterauthenticationhandler(_registration);
        }

大致的流程就是这样,具体的如何判断登录,注销,下一章再详细讲解。