Identity is not IClaimsIdentity using WIF (on ASP.

2020-07-18 10:06发布

问题:

I've got the WIF tools for VS2012RC, and I'm trying to get my ASP.NET MVC 4 project to use them. I've installed the NuGet package for Microsoft.IdentityModel.dll.

The MVC project is part of an Azure project, but I have the MVC project selected for startup right now.

Currently, I have the "Local Development Test STS" selected (with the default settings). When I execute the following code (in my HomeController Index view):

<p>Authenticated: @User.Identity.IsAuthenticated</p>
<p>Name: @User.Identity.Name</p>
@{
    var identity = User.Identity as Microsoft.IdentityModel.Claims.IClaimsIdentity;
    if (identity == null)
    {
        <p>Error: no identity claims to process!</p>
    }
    else
    {
        <table>
            <tr>
                <th>Type</th><th>Value</th><th>Issuer</th><th>Original Issuer</th>
            </tr>
            @foreach (var claim in identity.Claims)
            {
                <tr>
                    <td>@claim.ClaimType</td><td>@claim.Value</td><td>@claim.Issuer</td><td>@claim.OriginalIssuer</td>
                </tr>
            }
        </table>
    }
}

then I get output like this:

<p>Authenticated: True</p>
<p>Name: Terry</p>
<p>Error: no identity claims to process!</p>

Why aren't the claims being picked up?

Here's the relevant parts of web.config:

<configSections>
  <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" />
</configSections>
<appSettings>
  <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  <add key="webpages:Version" value="2.0.0.0" />
  <add key="webpages:Enabled" value="false" />
  <add key="PreserveLoginUrl" value="true" />
  <add key="ida:FederationMetadataLocation" value="http://localhost:13340/wsFederationSTS/FederationMetadata/2007-06/FederationMetadata.xml" />
  <add key="ida:ProviderSelection" value="localSTS" />
</appSettings>
<location path="FederationMetadata">
  <system.web>
    <authorization>
      <allow users="*" />
    </authorization>
  </system.web>
</location>
<system.web>
  <authorization>
    <deny users="?" />
  </authorization>
  <authentication mode="None" />
  <profile defaultProvider="DefaultProfileProvider">
    <providers>
      <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
    </providers>
  </profile>
  <membership defaultProvider="DefaultMembershipProvider">
    <providers>
      <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
    </providers>
  </membership>
  <roleManager defaultProvider="DefaultRoleProvider">
    <providers>
      <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
    </providers>
  </roleManager>
  <sessionState mode="InProc" customProvider="DefaultSessionProvider">
    <providers>
      <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
    </providers>
  </sessionState>
</system.web>
<system.webServer>
  <validation validateIntegratedModeConfiguration="false" />
  <modules runAllManagedModulesForAllRequests="true">
    <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
    <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
  </modules>
</system.webServer>
<system.identityModel>
  <identityConfiguration>
    <audienceUris>
      <add value="http://localhost:50332/" />
    </audienceUris>
    <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <trustedIssuers>
        <add thumbprint="9B74CB2F320F7AAFC156E1252270B1DC01EF40D0" name="LocalSTS" />
        <add thumbprint="C00C014CA49559426B6D70162C2D89689E9397FF" name="https://nitoprograms-0.accesscontrol.windows.net/" />
      </trustedIssuers>
    </issuerNameRegistry>
    <certificateValidation certificateValidationMode="None" />
  </identityConfiguration>
</system.identityModel>
<system.identityModel.services>
  <federationConfiguration>
    <cookieHandler requireSsl="false" />
    <wsFederation passiveRedirectEnabled="true" issuer="http://localhost:13340/wsFederationSTS/Issue" realm="http://localhost:50332/" reply="http://localhost:50332/" requireHttps="false" />
  </federationConfiguration>
</system.identityModel.services>

回答1:

When running locally (on a Windows 8 Release Preview machine), the following code does work:

<p>Authenticated: @User.Identity.IsAuthenticated</p>
<p>Name: @User.Identity.Name</p>
@{
    dynamic identity = User.Identity;
    <table>
        <tr>
            <th>Type</th><th>Value</th><th>Issuer</th><th>Original Issuer</th>
        </tr>
        @foreach (var claim in identity.Claims)
        {
            <tr>
                <td>@claim.Type</td><td>@claim.Value</td><td>@claim.Issuer</td><td>@claim.OriginalIssuer</td>
            </tr>
        }
    </table>
}

This leads me to believe that the WIF tools for VS2012RC only support .NET 4.5 as a target.

When running locally, the actual runtime is .NET 4.5, which has core identity changes related to WIF (compare this diagram for .NET 4.0 with this diagram for .NET 4.5). So, by using dynamic (and changing ClaimType to Type), I'm able to access the .NET 4.5 WIF runtime locally (even though the project targets .NET 4.0).

I tried deploying to the cloud, but the app complained about not finding System.IdentityModel.Services.dll (since Azure only uses .NET 4.0 currently). Not too big of a deal for me since I don't plan on deploying until .NET 4.5 is out.



回答2:

I think you are missing the WIF modules in ASP.NET config for "classic" mode (not sure how you are running the app). Try adding these:

 <system.web>
    <httpModules>
          <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
          <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </httpModules>...
 </system.web>

See here for more details on HTTP Modules in classic and integrated modes: http://msdn.microsoft.com/en-us/library/ms227673.aspx