我们已经运行了通过令牌身份验证使用内部用户的ASP.NET MVC Web应用程序。这是以ASP.NET MVC模板提供的标准方式实现的。
现在,我们需要扩展此身份验证模型,并允许外部Azure AD用户登录配置租户的Web应用程序。我已经找到了Azure AD方面的所有内容。感谢microsoft github示例here
现在,个人帐户身份验证和 Azure AD 都可以独立运行。但它没有合作。当我将两个中间件一起插入其给出问题时。
这是我的startup_auth.cs文件。
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
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))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
string ClientId = ConfigurationManager.AppSettings["ida:ClientID"];
string Authority = "https://login.microsoftonline.com/common/";
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = ClientId,
Authority = Authority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = false,
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (context) =>
{
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl;
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
return Task.FromResult(0);
},
SecurityTokenValidated = (context) =>
{
// retriever caller data from the incoming principal
string issuer = context.AuthenticationTicket.Identity.FindFirst("iss").Value;
string UPN = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
if (
// the caller comes from an admin-consented, recorded issuer
(db.Tenants.FirstOrDefault(a => ((a.IssValue == issuer) && (a.AdminConsented))) == null)
// the caller is recorded in the db of users who went through the individual onboardoing
&& (db.Users.FirstOrDefault(b =>((b.UPN == UPN) && (b.TenantID == tenantID))) == null)
)
// the caller was neither from a trusted issuer or a registered user - throw to block the authentication flow
throw new SecurityTokenValidationException();
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
context.OwinContext.Response.Redirect("/Home/Error?message=" + context.Exception.Message);
context.HandleResponse(); // Suppress the exception
return Task.FromResult(0);
}
}
});
}
}
此配置适用于本地用户帐户,但不适用于AAD。要启用AAD身份验证,我需要配置UseCookieAuthentication部分,如下所示。这将破坏我的本地用户帐户身份验证。
app.UseCookieAuthentication(new CookieAuthenticationOptions {});
基本上我需要删除本地用户的中间件以使AAD工作。
我的意思是AAD没有工作,我无法进行任何受[Authoroze]属性保护的安全行动。它的调用事件SecurityTokenValidated,我能够获得所有AAD声明,并能够验证我的自定义租户。但只有在最后我重定向到我的应用程序的root,这是安全的操作,它扔回我的自定义登录页面。似乎它没有在内部登录用户,也没有创建必要的身份验证cookie。
我很感激我在这里可能缺少的任何想法。
由于
答案 0 :(得分:1)
要支持来自社交数据提供者的个人帐户和其他帐户,只需使用OWIN组件添加它们。
要注销从Azure AD登录的用户,我们需要注销从Web应用程序和Azure AD发布的cookie。首先,我修改了ApplicationUser
类以添加自定义声明,以检测用户是从Azure AD登录还是从以下各个帐户登录。
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
if((this.Logins as System.Collections.Generic.List<IdentityUserLogin>).Count>0)
userIdentity.AddClaim(new Claim("idp", (this.Logins as System.Collections.Generic.List<IdentityUserLogin>)[0].LoginProvider));
return userIdentity;
}
}
然后我们可以更改LogOff
方法以支持从Azure AD注销以清除Azure AD中的Cookie:
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
var idpClaim = ClaimsPrincipal.Current.Claims.FirstOrDefault(claim => { return claim.Type == "idp"; });
if (idpClaim!=null)
HttpContext.GetOwinContext().Authentication.SignOut(
OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
return RedirectToAction("Index", "Home");
}
答案 1 :(得分:0)
听起来您的OpenID Connect身份验证未连接到您的Cookie身份验证。您似乎需要在SignInAsAuthenticationType
中指定与OpenIdConnectAuthenticationOptions
或AuthenticationType
身份验证类型中的CookieAuthenticationOptions
匹配的ExternalCookie
。