asp.net-mvc - Azure Active Directory - 身份验证单租户
问题描述
我正在尝试为我的 Web 应用程序配置 Azure AD 单租户身份验证。我已经按照 .NET 的快速入门指南进行操作,但是我注意到我实际上可以使用任何 Microsoft Office 365 帐户登录我的应用程序,而不仅仅是我想要的租户中的那些。
有人可以指出我的错误吗?我希望这拒绝不在我的租户中的登录(@mydomain.com 电子邮件地址)
启动.cs
public class Startup
{
// The Client ID (a.k.a. Application ID) is used by the application to uniquely identify itself to Azure AD
string clientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"];
// RedirectUri is the URL where the user will be redirected to after they sign in
string redirectUrl = System.Configuration.ConfigurationManager.AppSettings["redirectUrl"];
// Tenant is the tenant ID (e.g. contoso.onmicrosoft.com, or 'common' for multi-tenant)
static readonly string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"];
// Authority is the URL for authority, composed by Azure Active Directory endpoint and the tenant name (e.g. https://login.microsoftonline.com/contoso.onmicrosoft.com)
string authority = String.Format(System.Globalization.CultureInfo.InvariantCulture, System.Configuration.ConfigurationManager.AppSettings["Authority"], tenant);
/// <summary>
/// Configure OWIN to use OpenIdConnect
/// </summary>
/// <param name="app"></param>
///
public void Configuration(IAppBuilder app)
{
app.UseKentorOwinCookieSaver();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions {
CookieName = "My Workspace",
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
AuthenticationMode = AuthenticationMode.Active,
CookieSecure = CookieSecureOption.Always,
CookieManager = new SystemWebChunkingCookieManager(),
CookieDomain = "mydomain.com",
ExpireTimeSpan = new TimeSpan(4, 0, 0),
SlidingExpiration = true
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// Sets the ClientId, authority, RedirectUri as obtained from web.config - as well as UseTokenLifetime
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUrl,
UseTokenLifetime = false,
// PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
PostLogoutRedirectUri = redirectUrl,
//Scope is the requested scope: OpenIdConnectScopes.OpenIdProfileis equivalent to the string 'openid profile': in the consent screen, this will result in 'Sign you in and read your profile'
Scope = OpenIdConnectScope.OpenIdProfile,
// ResponseType is set to request the id_token - which contains basic information about the signed-in user
ResponseType = OpenIdConnectResponseType.IdToken,
// ValidateIssuer set to false to allow work accounts from any organization to sign in to your application
// To only allow users from a single organizations, set ValidateIssuer to true and 'tenant' setting in web.config to the tenant name or Id (example: contoso.onmicrosoft.com)
// To allow users from only a list of specific organizations, set ValidateIssuer to true and use ValidIssuers parameter
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuers = new List<string>() {
"https://login.microsoftonline.com/my-client(application)-id-is-here"
}
},
// OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed
}
}
);
}
/// <summary>
/// Handle failed authentication requests by redirecting the user to the home page with an error in the query string
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
if (context.Exception.Message.Contains("IDE21323")) {
context.HandleResponse();
context.OwinContext.Authentication.Challenge();
} else {
context.HandleResponse();
context.Response.Redirect("/?errormessage=" + context.Exception.Message);
}
return Task.FromResult(0);
}
我在 HomeController.cs 中的 SignIn / SignOut 方法
public void SignIn()
{
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties { RedirectUri = "/" },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
/// <summary>
/// Send an OpenID Connect sign-out request.
/// </summary>
public void SignOut()
{
HttpContext.GetOwinContext().Authentication.SignOut(
OpenIdConnectAuthenticationDefaults.AuthenticationType,
CookieAuthenticationDefaults.AuthenticationType);
}
我希望我的应用程序只允许从我的活动目录登录 - 而不是任何 office365 帐户。我还希望它检测用户是否在机器上已经有一个用于另一个帐户的 cookie,并且像 Microsoft 所做的那样,他们显示一条消息说明......“您当前登录的帐户无权访问这个应用程序。”
此外,在 Azure 门户中,在我的 Active Directory 应用程序下,我为选项“谁可以使用此应用程序或 api”选择了“仅限此组织目录中的帐户 (mydomain.com)”。
网页配置
我的 web.config 中有以下键
<add key="ClientId" value="MY CLIENT ID FROM AZURE AD APP" />
<add key="Tenant" value="MY TENANT ID FROM AZURE AD APP" />
<add key="Authority" value="https://login.microsoftonline.com/{0}/v2.0" />
我究竟做错了什么?
更新
尽管该应用程序仍允许从任何 Office 365 帐户登录,但我已经能够将其他代码添加IssuerValidator
到TokenValidationParameters
. 我没有检查 JWT 是否有我期望的正确 TID 和 IDP 值。奇怪的是,即使我使用不在我的 Active Directory 中的帐户登录,TID 也是相同的 - 但是 IDP 值显示在使用“有效”帐户进行身份验证时不存在的地方。
解决方案
推荐阅读
- azure - Azure 数据工厂从 foreach 值中获取数据
- kubernetes - 自动将 imagePullSecrets 添加到 ServiceAccount
- csv - 来自 Google Cloud Storage 的 BigQuery 表
- optimization - OPL CPLEX,向我的优化问题添加相似性约束的问题
- swift - 在核心数据中存储测量值
- ruby-on-rails - 部署到 heroku 失败,因为 sqlite3 在 gems 中,即使它不是
- javascript - 使用图表js打印图表
- css - 在悬停时显示另一个元素 - css
- maven - Maven / Nexus:在构建目录中下载工件元数据
- airflow - 具有夏令时的气流调度