可以轻松创建基于Windows域用户进行身份验证的 ASP.NET MVC 应用程序。创建一个使用实体框架存储的个人帐户也很容易。事实上,两者都有项目模板。
但我想在同一个应用程序中使用 BOTH 种类的身份验证。我试图结合两个项目模板的代码。我在Startup.Auth.cs中遇到了问题。
// from "Individual Accounts" template
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
中间件中存在cookie身份验证似乎会导致域身份未经身份验证。如果我采用此行,域身份验证将起作用。但没有它,我似乎无法支持个人用户帐户。
我已经下载了katana项目源代码并检查了CookieAuthenticationHandler.cs,但我不太明白它是如何在OWIN管道的上下文中运行的。
如何使用ASP.net身份框架允许我的应用程序从Windows域或特定于应用程序的用户存储中验证用户?
答案 0 :(得分:16)
最简单的方法是将2个不同的演示项目仅用于身份验证/授权。
这具有依赖现有框架和标准配置的优势。
从那里开始,您决定
为每个AD用户创建Identity用户更容易实现。然后,整个应用程序中可以存在相同的cookie和过滤器。
在这种情况下,您可以
或者,如果您想要一个真正的统一解决方案,请使用MohammadYounes / Owin-MixedAuth
Install-Package OWIN-MixedAuth
在 Web.config
中<location path="MixedAuth">
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
在Startup.Auth.cs
中app.UseMixedAuth(cookieOptions);
处理程序使用ApplyResponseChallengeAsync
确认请求是 401挑战 。如果是,则重定向到回调路径以从IIS请求身份验证,该IIS配置为查询AD。
AuthenticationResponseChallenge challenge = Helper.LookupChallenge(
Options.AuthenticationType, Options.AuthenticationMode);
401质询 是由未经授权的用户尝试使用需要身份验证的资源引起的
处理程序使用InvokeAsync
检查请求是否来自回调路径(IIS),然后调用AuthenticateCoreAsync
protected async override System.Threading.Tasks.Task<AuthenticationTicket>
AuthenticateCoreAsync()
{
AuthenticationProperties properties = UnpackStateParameter(Request.Query);
if (properties != null)
{
var logonUserIdentity = Options.Provider.GetLogonUserIdentity(Context);
if (logonUserIdentity.AuthenticationType != Options.CookieOptions.AuthenticationType
&& logonUserIdentity.IsAuthenticated)
{
AddCookieBackIfExists();
ClaimsIdentity claimsIdentity = new ClaimsIdentity(
logonUserIdentity.Claims, Options.SignInAsAuthenticationType);
// ExternalLoginInfo GetExternalLoginInfo(AuthenticateResult result)
claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier,
logonUserIdentity.User.Value, null, Options.AuthenticationType));
//could grab email from AD and add it to the claims list.
var ticket = new AuthenticationTicket(claimsIdentity, properties);
var context = new MixedAuthAuthenticatedContext(
Context,
claimsIdentity,
properties,
Options.AccessTokenFormat.Protect(ticket));
await Options.Provider.Authenticated(context);
return ticket;
}
}
return new AuthenticationTicket(null, properties);
}
AuthenticateCoreAsync
使用AddCookieBackIfExists
来阅读AD创建的声明Cookie,并创建自己的声明。
为AD用户提供与Web用户相同的基于声明的Cookie。 AD现在与任何其他第三方身份验证器一样( Google,FB,LinkedIN )
答案 1 :(得分:7)
由于这个原因,我还没有能够使用预先烘焙的解决方案进行身份验证。在我们的项目中,过去的几年(和敏捷方法)让我们有4种不同的方式来进行身份验证,这很烦人,但我们支持该领域的所有旧版应用程序,因此我们必须保留所有这些(至少目前为止)。
我最终创建了一个工厂,它确定了身份验证机制(通过令牌格式,存在其他一些东西),然后返回一个包装器,其中包含验证该身份验证方法和设置主体的逻辑。
这将在自定义 HTTP模块中启动,以便在请求到达控制器之前构建和验证主体。在你的情况下,我认为Windows Auth将是最终的后备。在我们的 Web API 应用程序中,我们采用相同的方法,但通过委托处理程序而不是 HTTP模块。你可以说,它是一种本地令牌联合。当前实现允许我们添加或修改任何验证过程,或添加任何其他令牌格式;最后,用户最终会获得适当的身份或被拒绝。只用了几天就实现了。
答案 2 :(得分:2)
在我看来,这个问题的最佳答案是使用身份验证和授权框架。有很多可供选择(商业和免费)。当然,你可以写自己的,但我会劝阻它。很多非常聪明的人都错了。
我会看看IdentityServer3。它当然不是唯一的解决方案,但它是一个非常好的身份验证和授权框架。它是开源的,很容易快速启动和运行。您的用例很常见,您可以在上面的链接中找到一些非常有用的信息。清除授权和身份验证之间的分离,社交身份验证选项,易于使用封装用户声明的json Web令牌等。
它如何帮助您
IdentityServer3允许您配置Identity Providers来处理身份验证,并且有许多扩展点可以让您实现可以处理两种方案的责任链。来自docs:
IdentityServer支持使用外部身份提供程序进行身份验证。外部认证机制必须封装在Katana认证中间件中。
Katana本身附带谷歌,Facebook,Twitter,微软账户,WS-Federation和OpenID Connect的中间件 - 但也有社区开发的中间件(包括Yahoo,LinkedIn和SAML2p)。
要为外部提供程序配置中间件,请在项目中添加一个接受IAppBuilder和字符串作为参数的方法。
IdentityServer3通过浏览器登录窗口支持AD作为身份提供者,并将通过custom grant支持更具编程性的实现。您还可以查看here以获取有关IdentityServer3和AD身份验证的更多信息。
它也将支持Windows身份验证,您可以查看here以获取有关实现该功能的信息和示例。
还有一个非常好的入门示例here。
通过正确的配置,IdentityServer3可以满足您的要求。您将需要实现自己的身份验证提供程序并将它们插入到框架中,但除此之外没有更多内容。至于授权,那里也有很多选择。