[英]After SignIn User.Identity.Name is empty, but User.Identity.IsAuthenticated is set right
[英]After logging in 'User.Identity.Name' is null, but 'IsAuthenticated' is true when using Sustainsys.Saml2.Mvc integration
我有一個 ASP.NET MVC 5 應用程序,需要支持 SAML 2.0 身份驗證。 我正在評估Sustainsys.Saml.Mvc 。 我的控制器中的User.Identity.Name
屬性是一個空字符串,而User.Identity.IsAuthenticated
屬性是true
,我這輩子都弄不明白。
安裝 Sustainsys.Saml2.Mvc NuGet 包時,我必須執行以下操作:
Web.config 的內容:
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301880
-->
<configuration>
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<section name="sustainsys.saml2" type="Sustainsys.Saml2.Configuration.SustainsysSaml2Section, Sustainsys.Saml2" />
</configSections>
<connectionStrings>
...
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<!--
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.6.1" />
</system.Web>
-->
<system.web>
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1" requestValidationMode="2.0" />
<authentication mode="Forms">
<forms loginUrl="~/Saml2/SignIn" />
</authentication>
<membership defaultProvider="ABC">
<providers>
<clear />
<add name="ABC" type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionStringName="ADConnectionString" attributeMapUsername="sAMAccountName" />
</providers>
</membership>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
</system.web>
<system.webServer>
<handlers>
<add name="UrlRoutingHandler" type="System.Web.Routing.UrlRoutingHandler, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" path="Authorization/Permissions/*" verb="GET,POST" />
</handlers>
<staticContent>
<remove fileExtension="eot" />
<remove fileExtension="otf" />
<remove fileExtension="woff" />
<remove fileExtension="woff2" />
<remove fileExtension="ttf" />
<remove fileExtension="json" />
<mimeMap fileExtension="eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension="otf" mimeType="application/x-font-opentype" />
<mimeMap fileExtension="woff" mimeType="application/x-font-woff" />
<mimeMap fileExtension="woff2" mimeType="application/font-woff2" />
<mimeMap fileExtension="ttf" mimeType="application/x-font-ttf" />
<mimeMap fileExtension="json" mimeType="application/json" />
</staticContent>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</modules>
<httpErrors errorMode="Detailed" />
</system.webServer>
<sustainsys.saml2 entityId="http://localhost/MyMvcApp/Saml2" returnUrl="http://localhost/MyMvcApp/">
<identityProviders>
<add entityId="https://stubidp.sustainsys.com/Metadata" signOnUrl="https://stubidp.sustainsys.com/" allowUnsolicitedAuthnResponse="true" binding="HttpRedirect">
<signingCertificate fileName="~/App_Data/stubidp.sustainsys.com.cer" />
</add>
</identityProviders>
<!--<federations>
<add metadataLocation="http://localhost:52071/Federation" allowUnsolicitedAuthnResponse="true"/>
</federations>-->
<serviceCertificates>
<add fileName="~/App_Data/Sustainsys.Saml2.Tests.pfx" />
</serviceCertificates>
</sustainsys.saml2>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="false" />
</federationConfiguration>
</system.identityModel.services>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89b483f429c47342" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.121.2.0" newVersion="4.121.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory" from="foo@mycompany.com">
<network host="smtp.mycompany.com" port="25" defaultCredentials="true" />
<specifiedPickupDirectory pickupDirectoryLocation="..." />
</smtp>
</mailSettings>
</system.net>
<elmah>
<!--
See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for
more information on remote access and securing ELMAH.
-->
<security allowRemoteAccess="true" />
<errorLog type="Elmah.MemoryErrorLog, Elmah" size="50" />
</elmah>
<location path="elmah.axd" inheritInChildApplications="false">
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<!--
See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for
more information on using ASP.NET authorization securing ELMAH.-->
<authorization>
<allow users="..." />
<deny users="*" />
</authorization>
</system.web>
<system.webServer>
<handlers>
<add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
</handlers>
</system.webServer>
</location>
</configuration>
我目前正在通過我的筆記本電腦托管我的應用程序:
它在以下位置使用模擬身份提供者: https ://stubidp.sustainsys.com/
發布到 /MyApp/Saml2/Acs 的 XML:
<saml2p:Response Destination="http://localhost/MyApp/Saml2/Acs" ID="idb4440bf88fba449f8526760d4330dd53" Version="2.0" IssueInstant="2018-12-20T18:21:22Z" InResponseTo="idd9b8948ac5ac4c389bf65072169464ac"
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://stubidp.sustainsys.com/Metadata
</saml2:Issuer>
<Signature
xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="#idb4440bf88fba449f8526760d4330dd53">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>...</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<saml2p:Status>
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
<saml2:Assertion
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="_d6ffcd18-44ec-45db-bd74-9cf48ea1cfa2" IssueInstant="2018-12-20T18:21:22Z">
<saml2:Issuer>https://stubidp.sustainsys.com/Metadata</saml2:Issuer>
<saml2:Subject>
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">JohnDoe</saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData NotOnOrAfter="2018-12-20T18:23:22Z" InResponseTo="..." Recipient="http://localhost/MyApp/Saml2/Acs" />
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions NotOnOrAfter="2018-12-20T18:23:22Z">
<saml2:AudienceRestriction>
<saml2:Audience>http://localhost/MyApp/Saml2</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AuthnStatement AuthnInstant="2018-12-20T18:21:22Z" SessionIndex="42">
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
</saml2:Assertion>
</saml2p:Response>
我還在控制器上設置了Options.Logger
屬性,這就是我在調試輸出中得到的:
[Saml2, DEBUG]: Http POST binding extracted message
<saml2p:Response Destination="http://localhost/MyApp/Saml2/Acs" ...>...</saml2p:Response>
[Saml2, DEBUG]: Signature validation passed for Saml Response Microsoft.IdentityModel.Tokens.Saml2.Saml2Id
[Saml2, DEBUG]: Extracted SAML assertion _a5ee9c7f-4ca5-4693-a7f7-301ae5e6d4a6
[Saml2, INFO]: Successfully processed SAML response Microsoft.IdentityModel.Tokens.Saml2.Saml2Id and authenticated JohnDoe
調試應用程序時,我的 MVC 控制器中的User.Identity.Name
屬性為空。 對該對象的進一步檢查:
為什么在成功聲明 SAML 響應后System.Web.Mvc.Controller.User.Identity.Name
為空?
您已正確完成身份驗證。 並且您有一個工作會話身份驗證 cookie。
但是,您沒有的是與默認名稱聲明類型相匹配的聲明。 您有 NameIdentifier 聲明(默認情況下存根 idp 提供的內容)。 但是您沒有使用默認NameClaimType
的聲明
ClaimsIdentity
的Name
屬性實現為
return Claims.FirstOrDefault(c => c.Type == NameClaimType)?.Value;
因此,要獲取Name
屬性的值,您需要更改NameClaimType
(可以通過修改AcsCommandResultCreated
通知中創建的身份來完成)或讓您的 Idp 提供類型為http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
的屬性http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
。 您可以通過在 stubidp 表單的底部添加一個屬性來做到這一點。
我沒有使用身份服務器,但同樣的基本問題:
在User.Identity.Claims
下查看您的聲明,找到一個確實有您的用戶名的聲明。
然后,無論您在哪里配置令牌驗證,都必須將NameClaimType
設置為您在上面看到的那個:
然后,當中間件對其進行驗證時,它將將該聲明復制到UserName
中。 我假設這是 Windows 身份驗證 [sic] 的一些默認設置。
var tokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
Core 3.1 遇到同樣的問題:User.Identity.Name 屬性為空,而 User.Identity.IsAuthenticated 為真。 但是您可以通過在控制器中使用 HttpContectAccessor 來獲取名稱:
private readonly IHttpContextAccessor _httpContextAccessor;
public MyController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void AnyMethod()
{
var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
var user = _context.AspNetUsers.Find(userId);
var name = user.UserName;
...
}
在 Startup.cs 中添加服務:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.