Azure Ad SSO 成功收到 IdToken 但 Request.IsAuthenticated 为 false 并在 asp.net MVC 5 中声明为 null
Posted
技术标签:
【中文标题】Azure Ad SSO 成功收到 IdToken 但 Request.IsAuthenticated 为 false 并在 asp.net MVC 5 中声明为 null【英文标题】:Azure Ad SSO successful received IdToken but Request.IsAuthenticated is false and claims null in asp.net MVC 5 【发布时间】:2021-10-30 14:31:30 【问题描述】:我正在尝试使用 OWIN 中间件在 asp.net MVC 5 应用程序中实现 Azure AD SSO。 我关注了微软的文章:https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-aspnet-webapp
在完成所有这些之后,我成功通过身份验证并重定向回应用程序。 SSO 处理成功后,我可以在查询字符串中看到IDToken
。
但问题是Request.IsAuthenticated
始终为假,Claims
也为空。
这是为演示创建的新项目。我已经解决了与此问题相关的大多数堆栈溢出问题,但没有一个有效,我认为这可能是因为 OWN nuget 包版本。
这是我的代码:
Startup.cs:
[assembly: OwinStartup(typeof(ServerSide_SSO.Startup))]
namespace ServerSide_SSO
public class Startup
// The Client 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 redirectUri = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"];
// Tenant is the tenant ID (e.g. contoso.onmicrosoft.com, or 'common' for multi-tenant)
static string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"];
// Authority is the URL for authority, composed by Microsoft identity platform endpoint and the tenant name (e.g. https://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0)
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.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
//app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseCookieAuthentication(new CookieAuthenticationOptions()
CookieManager = new SystemWebCookieManager()
);
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
// Sets the ClientId, authority, RedirectUri as obtained from web.config
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUri,
// PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
PostLogoutRedirectUri = redirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
// ResponseType is set to request the code id_token - which contains basic information about the signed-in user
ResponseType = OpenIdConnectResponseType.IdToken,
// ValidateIssuer set to false to allow personal and 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
// To allow users from only a list of specific organizations, set ValidateIssuer to true and use ValidIssuers parameter
TokenValidationParameters = new TokenValidationParameters()
ValidateIssuer = false, // This is a simplification
NameClaimType = "name"
,
// OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
Notifications = new OpenIdConnectAuthenticationNotifications
AuthenticationFailed = OnAuthenticationFailed,
RedirectToIdentityProvider = context =>
Debug.WriteLine("Redirecting to identity provider for sign in..");
context.ProtocolMessage.EnableTelemetryParameters = false;
context.ProtocolMessage.ResponseMode = null;
return Task.FromResult(0);
,
AuthorizationCodeReceived = context =>
Debug.WriteLine("Authorization code received..");
return Task.FromResult(0);
,
SecurityTokenReceived = context =>
Debug.WriteLine("Token response received..");
return Task.FromResult(0);
,
SecurityTokenValidated = context =>
Debug.WriteLine("Token validated..");
return Task.FromResult(0);
,
TokenResponseReceived = context =>
Debug.WriteLine("Token response received..");
return Task.FromResult(0);
,
MessageReceived = context =>
Debug.WriteLine("Message received..");
return Task.FromResult(0);
);
/// <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)
context.HandleResponse();
context.Response.Redirect("/?errormessage=" + context.Exception.Message);
return Task.FromResult(0);
packages.config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.5.0.2" targetFramework="net472" />
<package id="bootstrap" version="3.4.1" targetFramework="net472" />
<package id="jQuery" version="3.4.1" targetFramework="net472" />
<package id="jQuery.Validation" version="1.17.0" targetFramework="net472" />
<package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net472" />
<package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net472" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net472" />
<package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net472" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net472" />
<package id="Microsoft.IdentityModel.JsonWebTokens" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.IdentityModel.Logging" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.IdentityModel.Protocols" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.IdentityModel.Tokens" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.11" targetFramework="net472" />
<package id="Microsoft.Owin" version="4.2.0" targetFramework="net472" />
<package id="Microsoft.Owin.Host.SystemWeb" version="4.2.0" targetFramework="net472" />
<package id="Microsoft.Owin.Security" version="4.2.0" targetFramework="net472" />
<package id="Microsoft.Owin.Security.Cookies" version="4.2.0" targetFramework="net472" />
<package id="Microsoft.Owin.Security.OpenIdConnect" version="4.2.0" targetFramework="net472" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net472" />
<package id="Modernizr" version="2.8.3" targetFramework="net472" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
<package id="Owin" version="1.0" targetFramework="net472" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.3.0" targetFramework="net472" />
<package id="WebGrease" version="1.6.0" targetFramework="net472" />
</packages>
web.config 没有设置身份验证模式
登录方法
public void SignIn()
if (!Request.IsAuthenticated)
HttpContext.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties RedirectUri = "/" ,
OpenIdConnectAuthenticationDefaults.AuthenticationType);
//return new EmptyResult();
声明控制器方法
public ActionResult Index()
var userAuthenticated = Request.IsAuthenticated;
var userClaims = User.Identity as System.Security.Claims.ClaimsIdentity;
//You get the user's first and last name below:
ViewBag.Name = userClaims?.FindFirst("name")?.Value;
// The 'preferred_username' claim can be used for showing the username
ViewBag.Username = userClaims?.FindFirst("preferred_username")?.Value;
// The subject/ NameIdentifier claim can be used to uniquely identify the user across the web
ViewBag.Subject = userClaims?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
// TenantId is the unique Tenant Id - which represents an organization in Azure AD
ViewBag.TenantId = userClaims?.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid")?.Value;
return View();
【问题讨论】:
【参考方案1】:我试图在我的本地设置一个重现但无法得到同样的问题,然后这个MS DOC 您使用的代码似乎是正确的,我尝试使用 OWIN 中间件NuGet packages
我的 MVC 应用程序(版本 .净 4.6.1):
从 PowerShell 运行:
Install-Package Microsoft.Owin.Security.OpenIdConnect
Install-Package Microsoft.Owin.Security.Cookies
Install-Package Microsoft.Owin.Host.SystemWeb
<package id="Microsoft.Owin" version="4.2.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security" version="4.2.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security.Cookies" version="4.2.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security.OpenIdConnect" version="4.2.0" targetFramework="net461" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="10.0.1" targetFramework="net461" />
<package id="Owin" version="1.0" targetFramework="net461" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.3.0" targetFramework="net461" />
</packages>
更多信息请参考以下链接:
。 Microsoft AAD Identity And Access Management With MVC 5 Web Application..
.Getting NULL Identity while authenticating user via Azure AD authentication| SO THREAD
.Request.IsAuthenticated is false after logging into Active Directory| MSDN.
【讨论】:
以上是关于Azure Ad SSO 成功收到 IdToken 但 Request.IsAuthenticated 为 false 并在 asp.net MVC 5 中声明为 null的主要内容,如果未能解决你的问题,请参考以下文章
Android/iOS:如何使用 SAML 协议通过 Azure AD 为移动设备提供 SSO
Azure AD 与 AWS IAM 集成实现SSO—下(AWS部分)
Azure AD 与 AWS IAM 集成实现SSO—上(Azure部分)
使用 Azure Active Directory 或 ADFS 或 AD 的 SSO