在我的Web应用程序中,我默认实现了表单身份验证。但对于内部用户,我使用AD进行身份验证。 我有一个通过LDAP公开的内部部署AD,我只是用来验证内部用户。
现在我们计划搬到天蓝色的地方。所以我们已经迁移到azure AD。
Azure AD的问题是我无法再使用页面内的表单来验证用户身份。我必须将用户重定向到azure的身份验证页面(OWIN OpenIDConnect)。有没有办法在我的本地应用程序中拥有用户名/密码,然后将它们发送到任何azure api /服务进行身份验证?
另一个问题是 - 现在我不能在我的web.config中使用表单身份验证作为默认值,或者它永远不会重定向到azure的身份验证页面。
有人可以帮忙吗?
注意:这是一个拥有多个用户的单租户WEB应用程序
答案 0 :(得分:4)
可以使用 OWIN CookieAuthentication和ASP.NET身份解决问题,以使用 OpenIdConnect 处理AzureAD身份验证的本地身份验证。
"另一个问题是 - 现在我不能在我的web.config中使用表单身份验证作为默认值,或者它永远不会重定向到azure的身份验证页面。"
如果未在<authentication mode="none" />
OWIN中设置web.config
,则无法从IIS接管应用程序的身份验证/授权过程。
在Startup
课程中,您需要设置Identity和OpenIdConnect管道。
如果您使用个人帐户生成新的MVC项目进行身份验证,除Startup
控制器Account
之外,您还可以看到Login
类的自动生成代码(下面的示例)直接身份验证和ExternalLogin
(第三方)的操作。您还可以通过查看ExternalLogin
和ExternalLoginCallback
操作中的Account
和Notification
操作,了解如何将外部登录提供程序(在您的案例中为AzureAD)映射到本地用户帐户,即应用程序本地标识存储中的一个{1}}控制器。
设置本地身份验证所需的最低要求的教程
Adding-minimal-OWIN-Identity-Authentication-to-an-Existing-ASPNET-MVC-Application
设置OpenIdConnect时如果设置RedirectToIdentityProvider
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
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<SystemUserManager, SystemUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
// Used to skip login prompt for trusted tenant
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = async (context) =>
{
context.ProtocolMessage.DomainHint = "someDomainName";
},
}
});
}
}
(如下所示)并将 domain_hint 参数设置为已验证的域在Azure Active Directory(Azure管理门户)中具有单点登录的域部分下,如果已在已加入域的计算机上进行了身份验证,则用户应跳过提示页面。
domain_hint - 此参数不是OpenID Connect标准的一部分。天蓝 AD引入它以允许您指定希望用户进行身份验证的IdP 用。假设您的应用信任联合Azure AD租户。使用默认请求, 用户首先会看到Azure AD身份验证页面并被重定向到 仅在文本框中键入用户名后才联合ADFS。如果你发送 domain_hint参数设置为联合域,Azure AD页面是 跳过,请求直接进入与租户关联的ADFS。如果 用户正在从Intranet访问您的应用程序,因此已经过身份验证 ADFS,实际上可以实现无缝的单点登录体验。
使用Azure Active Directory for Web Applications进行现代身份验证第118页
还有其他参数,例如提示,可用于控制身份验证流程。
http://openid.net/specs/openid-connect-core-1_0.html
<强> Startup.Auth 强>
public class ExampleAuthorize : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return httpContext.User.IsInRole(this.Roles);
}
protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{"action", "Login"},{"controller", "Account"}
});
}
}
当未经身份验证的用户尝试访问受保护的代码时,他们将被定向到Azure登录页面。解决此问题的一种方法是创建自定义属性,并将其定向到所需的登录页面。
RedirectToIdentityProvider
更新评论
Resource Owner Password Credentials Grant(即用户名和密码)流可以直接用作授权许可,但只应在完全必要的地方使用(参见接受的答案)How to accept user credentials programmatically。示例项目Authenticating to Azure AD non-interactively using a username & password
如果只是一个自定义的AzureAD登录页面来实现一致的外观,那么添加AzureAD custom branding是一个选项。
未经测试 -
您可以尝试在prompt="none"
请求中设置用户名和密码参数。根据{{3}}设置app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = "https://login.windows.net/yourcompany.onmicrosoft.com",
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = async (context) =>
{
context.ProtocolMessage.Username = context.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["username"];
context.ProtocolMessage.Password = context.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["password"];
// Its my understanding that setting prompt="none" should tell the server not to display any authentication or consent user interface pages however this has not worked for me
// context.ProtocolMessage.Prompt = "none";
},
}
});
应该告诉服务器&#34;不显示任何身份验证或同意用户界面页面&#34; (见代码和评论)。
中间件设置 -
public void Login(string username, string password, string redirectUri, string loginProvider)
{
AuthenticationProperties properties = new AuthenticationProperties();
properties.RedirectUri = RedirectUri;
properties.Dictionary.Add("username", username);
properties.Dictionary.Add("password", password);
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, loginProvider);
}
在您的登录操作中 -
.player{
background: black;
height: 100px;
display: flex;
}
.button{
background: blue;
height: 100px;
width: 24px;
display: block;
}
.flexible{
flex: 1;
}
答案 1 :(得分:2)
经过大量研究后我得出结论:
1)在Web应用程序中,无法将用户名/密码直接传递给azure AD进行身份验证,就像使用内部部署AD(LDAP)一样。这不是限制,但可以被视为安全实现。
2)最多可以使用 RedirectToIdentityProvider和domain_hint 跳过azure门户页面。
3) ADAL ,可以将用户凭据传递给azure AD进行身份验证仅适用于本机客户端,本机客户端希望允许用户访问另一种资源(网络API,服务等)
4)要在基于表单的身份验证之上使用azure AD,您必须在web.config中将身份验证模式设置为none,并且创建新的授权过滤器以将未经授权的用户重定向到基于表单的登录页面。或者您可以使用以下URL中的答案: Redirect user to custom login page when using Azure AD
答案 2 :(得分:0)
除了来自cID的解决方案,请查看Azure B2C以存储您的用户: https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-overview/
使用B2C,您拥有一个完整的OWIN / OpenID Connect数据库,但您必须将现有的表单数据库迁移到那里。
此解决方案的第二部分是预览MSAL库,它结合了AD和B2C的登录