Asp.net web api 向经典ASP.NET Web窗体应用程序和Web API应用程序添加共享身份验证

Asp.net web api 向经典ASP.NET Web窗体应用程序和Web API应用程序添加共享身份验证,asp.net-web-api,owin,openid-connect,msal,Asp.net Web Api,Owin,Openid Connect,Msal,我正在用开放Id连接设计替换共享cookie身份验证设计 上下文:这两个web应用程序当前使用FormsAuthCookie与共享的AuthCookiecookie和machineKeys进行身份验证 系统: 一个经典的Web表单应用程序,FormsAuthentication,cookie=AuthCookie,主机/login.aspx 集成的Web API应用程序,FormsAuthentication,cookie=AuthCookie 问题1:Microsoft的开放Id连接库需要

我正在用开放Id连接设计替换共享cookie身份验证设计

上下文:这两个web应用程序当前使用
FormsAuthCookie
与共享的
AuthCookie
cookie和
machineKeys
进行身份验证

系统:

  • 一个经典的Web表单应用程序,FormsAuthentication,
    cookie=AuthCookie
    ,主机
    /login.aspx
  • 集成的Web API应用程序,FormsAuthentication,
    cookie=AuthCookie
问题1:Microsoft的开放Id连接库需要OWIN。我无法将经典Web表单应用程序转换为OWIN应用程序,因为OWIN需要集成管道,这将破坏依赖于经典管道的Spring.NET库

操作1A:将Web API转换为OWIN,并添加了对Open Id Connect的支持

操作1B:将身份验证从经典站点移动到Web API

问题2:身份验证后,我必须能够使用这两个系统

操作2:在开放Id连接重定向上,Web API将使用存储在开放Id连接cookie中的JWT承载令牌。Web API将创建一个经典应用程序将使用的附加cookie(
AuthCookie

问题3:如何使这两个cookie保持同步?用户必须同时登录或注销这两个系统。如果一个cookie被意外删除,而另一个cookie没有被删除,会发生什么情况

问题4:Web API未从Microsoft Open Id Connect接收Cookie,但对my Web API的后续请求未接收Cookie,并且未设置
HttpContext.Current.User

经典Web表单代码:

<authentication mode="Forms">
        <forms loginUrl="webapi/login" name="LycheeAuthCookie" slidingExpiration="true" path="/" />
</authentication>

Web API代码:

Startup.cs:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationMode = AuthenticationMode.Passive }); //Web API should return 401 not redirect to /login. The SPA will handle that
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
                ClientId = Config.ApplicationId,
                Authority = authority,
                RedirectUri = $"webapi/openIdRedirect",
                PostLogoutRedirectUri = $"webapi/openIdLogout",
                ResponseType = OpenIdConnectResponseType.IdToken,
                Scope = OpenIdConnectScope.OpenIdProfile,
                AuthenticationMode = AuthenticationMode.Passive, //Web API should return 401 not redirect to /login. The SPA will handle that
});
...
private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) //Called on Open Id Connect authentication success
        {
            var newTicket = new FormsAuthenticationTicket(1,
                userId,
                DateTime.Now.AddMinutes(int.Parse(claims.FindFirst("iat").Value)),
                false,
                DateTime.Now.AddMinutes(int.Parse(claims.FindFirst("exp").Value)),
                false,
                "roles and permissions",
                FormsAuthentication.FormsCookiePath);
            var cookie = new HttpCookie("AuthCookie");
            cookie.Value = FormsAuthentication.Encrypt(newTicket);
            cookie.Expires = newTicket.Expiration;
            HttpContext.Current.Response.Cookies.Add(cookie);
}
Redirect(redirectUrl);
Startup.cs:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(新的CookieAuthenticationOptions{AuthenticationMode=AuthenticationMode.Passive})//Web API应返回401而不是重定向到/登录。水疗中心会处理的
app.UseOpenIdConnectAuthentication(新的OpenIdConnectAuthenticationOptions
{
ClientId=Config.ApplicationId,
权威=权威,
重定向URI=$“webapi/openIdRedirect”,
PostLogoutRedirectUri=$“webapi/openIdLogout”,
ResponseType=OpenIdConnectResponseType.IdToken,
Scope=OpenIdConnectScope.OpenIdProfile,
AuthenticationMode=AuthenticationMode.Passive,//Web API应返回401而不是重定向到/login。SPA将处理该问题
});
...
私有任务OnSecurityTokenValidated(SecurityTokenValidatedNotification上下文)//在开放Id连接身份验证成功时调用
{
var newTicket=新表单身份验证单(1,
用户ID,
DateTime.Now.AddMinutes(int.Parse(claims.FindFirst(“iat”).Value)),
假,,
DateTime.Now.AddMinutes(int.Parse(claims.FindFirst(“exp”).Value)),
假,,
“角色和权限”,
FormsAuthentication.FormScookePath);
var cookie=新的HttpCookie(“AuthCookie”);
cookie.Value=FormsAuthentication.Encrypt(newTicket);
cookie.Expires=newTicket.expirement;
HttpContext.Current.Response.Cookies.Add(cookie);
}
重定向(重定向URL);

如果您的网站位于同一域,即。“https://localhost,并且您共享相同的
.AspNet.Cookies
,那么它就可以工作了

对于这两个网站,请添加OWIN中间件,将项目设置为IIS集成管道模式,并添加以下
Startup.cs
文件:

网站1位于“/”-活动:

[程序集:OwinStartup(typeof(…MyStartup))]
名称空间MyNamespace
{
公营创业
{
公共无效配置(IAppBuilder应用程序)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication();
app.UseOpenIdConnectAuthentication();
}
}
}
网站2位于“/api”-被动:

[程序集:OwinStartup(typeof(…MyStartup))]
名称空间MyNamespace
{
公营创业
{
公共无效配置(IAppBuilder应用程序)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(新的Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions{
AuthenticationType=CookieAuthenticationDefaults.AuthenticationType
});
}
}
}