向经典 ASP.NET Web 窗体应用和 Web API 应用添加共享身份验证
Posted
技术标签:
【中文标题】向经典 ASP.NET Web 窗体应用和 Web API 应用添加共享身份验证【英文标题】:Add shared authentication to a Classic ASP.NET Web Forms app and a Web API app 【发布时间】:2021-02-27 05:27:06 【问题描述】:我正在用 Open Id Connect 替换共享 cookie 身份验证设计。
上下文:这两个网络应用程序当前使用FormsAuthentication
,共享AuthCookie
cookie 和machineKeys
。
系统:
经典的 Web 表单应用程序,FormsAuthentication,cookie=AuthCookie
,主机/login.aspx
一个集成的 Web API 应用程序,FormsAuthentication,cookie=AuthCookie
问题 1:Microsoft 的 Open Id Connect 库需要 OWIN。我无法将经典 Web 窗体应用程序转换为 OWIN 应用程序,因为 OWIN 需要集成管道,这会破坏依赖于经典管道的 Spring.NET 库。
操作 1A:将 Web API 转换为 OWIN 并添加对 Open Id Connect 的支持。
操作 1B:将身份验证从经典站点转移到 Web API。
问题 2:身份验证后,我必须能够同时使用这两个系统。
操作 2:在 Open Id Connect 重定向时,Web API 将使用存储在 Open Id Connect cookie 中的 JWT 不记名令牌。 Web API 将创建一个额外的 cookie (AuthCookie
),经典应用将使用该 cookie。
问题 3:如何使这两个 cookie 保持同步?用户必须同时登录或退出这两个系统。如果一个 cookie 被意外删除而另一个没有被删除,会发生什么?
问题 4:Web API 未从 Microsoft Open Id Connect 接收 cookie,但对我的 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);
【问题讨论】:
【参考方案1】:如果您将您的网站托管在同一个域上,即“https://localhost”,并且您共享相同的.AspNet.Cookies
,那么它将起作用!
为这两个网站添加OWIN中间件,将您的项目设置为IIS集成管道模式,并添加以下Startup.cs
文件:
“/”处的网站 1 - 活动:
[assembly: OwinStartup(typeof(...MyStartup))]
namespace MyNamespace
public class Startup
public void Configuration(IAppBuilder app)
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication();
app.UseOpenIdConnectAuthentication();
位于“/api”的网站 2 - 被动:
[assembly: OwinStartup(typeof(...MyStartup))]
namespace MyNamespace
public class Startup
public void Configuration(IAppBuilder app)
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType
);
【讨论】:
以上是关于向经典 ASP.NET Web 窗体应用和 Web API 应用添加共享身份验证的主要内容,如果未能解决你的问题,请参考以下文章