4

ADFS 2.0 を使用したパッシブ RP である ASP.NET MVC アプリケーションがあります。このアプリケーションは、承認されていないすべてのユーザーを ADFS にリダイレクトします。ログインが成功すると、ユーザーはクレームを含むトークンを使用して Web アプリにリダイレクトされます。ここには本当に新しいものはありません。

私が今やりたいことは、発行されたトークンを使用して WCF サービスを呼び出すことです。これにより、このサービスは ADFS に戻ってすべてのセキュリティ ハンドシェイクを再度実行する必要がなくなります。

何時間もの調査の結果、最終的にサービスを呼び出すことができましたが、サービス内で次のコードを使用すると、ユーザーはまだ認証されていません。

public string GetName()
{
    var user = Thread.CurrentPrincipal.Identity as ClaimsIdentity;
    if (user != null && user.IsAuthenticated)
    {
        return user.FindFirst(x => x.Type == ClaimTypes.NameIdentifier).Value;
    }
    return "Unable to find your username. Something went wrong .... sorry!";
}

このトピックには何百もの記事やその他のスタックオーバーフローの質問があることを認識していますが、サービスを正常に呼び出すことができても、ユーザーが認証されない理由を見つけることができませんでした.

これを支援するために必要なその他のコードと構成の詳細:

ウェブアプリ

サービスコール

var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
binding.Security.Message.EstablishSecurityContext = true;
binding.Security.Message.IssuerAddress = new EndpointAddress("https://fs.server.com/adfs/services/trust");

var endpoint = new EndpointAddress("https://" + "localhost/service" + "/user.svc");

var factory = new ChannelFactory<IUser>(binding, endpoint);
factory.Credentials.SupportInteractive = false;
factory.Credentials.UseIdentityConfiguration = true;

var context = (BootstrapContext)((ClaimsIdentity)Thread.CurrentPrincipal.Identity).BootstrapContext;
var channel = factory.CreateChannelWithIssuedToken(context.SecurityToken, endpoint);

ViewBag.Username = channel.GetName();
((IServiceChannel)channel).Close();

return View();

Web.config

 <configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <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="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="ida:FederationMetadataLocation" value="https://fs.server.com:49160/FederationMetadata/2007-06/FederationMetadata.xml" />
    <add key="ida:Issuer" value="https://fs.server.com:49160/adfs/ls/" />
    <add key="ida:ProviderSelection" value="productionSTS" />
  </appSettings>
  <system.identityModel>
    <identityConfiguration saveBootstrapContext="true">
      <audienceUris>
        <add value="https://localhost/rp_poc" />
      </audienceUris>
      <issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
        <authority name="https://fs.server.com/adfs/services/trust">
          <keys>
            <add thumbprint="723C3A29732FC61F3BE96487E8560F749D1D8256" />
          </keys>
          <validIssuers>
            <add name="http://fs.server.com/adfs/services/trust" />
          </validIssuers>
        </authority>
      </issuerNameRegistry>
    </identityConfiguration>
  </system.identityModel>
  <system.identityModel.services>
    <federationConfiguration>
      <cookieHandler requireSsl="true" />
      <wsFederation passiveRedirectEnabled="true" issuer="https://fs.server.com:49160/adfs/ls/" realm="https://localhost/rp_poc" requireHttps="true" />
    </federationConfiguration>
  </system.identityModel.services>  
  <system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" requestValidationMode="4.5" />
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers" />
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.WebPages" />
      </namespaces>
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <modules>
      <remove name="FormsAuthentication" />
      <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>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

WCF サービス

Web.config

<configuration>
  <configSections>
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
  </configSections>
  <system.identityModel>
    <identityConfiguration saveBootstrapContext="true">
      <issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
        <authority name="https://fs.server.com/adfs/services/trust">
          <keys>
            <add thumbprint="723C3A29732FC61F3BE96487E8560F749D1D8256" />
          </keys>
          <validIssuers>
            <add name="http://fs.server.com/adfs/services/trust" />
          </validIssuers>
        </authority>
      </issuerNameRegistry>
      <audienceUris>
        <add value="https://localhost/rp_poc" />
      </audienceUris>
    </identityConfiguration>
  </system.identityModel>
  <system.serviceModel>
    <bindings>
      <ws2007FederationHttpBinding>
        <binding>
          <security mode ="TransportWithMessageCredential">
            <message issuedKeyType ="BearerKey" establishSecurityContext="true">
              <issuer address ="https://fs.server.com/adfs/services/trust"
                      binding ="ws2007HttpBinding" />
            </message>
          </security>
        </binding>
      </ws2007FederationHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="DefaultBehaviour" >
          <serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
          <serviceMetadata httpGetEnabled="true" />
          <serviceCredentials useIdentityConfiguration="true">
            <serviceCertificate findValue="74 0A FE 19 E9 F0 53 9C 46 D9 F2 D6 56 A7 0C E8" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber">
            </serviceCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="POC.Security.ServiceClient.User" behaviorConfiguration="DefaultBehaviour" >
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
        <endpoint contract="POC.Security.ServiceClient.IUser" binding="ws2007FederationHttpBinding" address=""/>
      </service>
    </services>
    <diagnostics>
      <messageLogging maxMessagesToLog="25000" logEntireMessage="true"
                      logMessagesAtServiceLevel="false"
                      logMalformedMessages="true" logMessagesAtTransportLevel="true">
        <filters>
          <clear/>
        </filters>
      </messageLogging>
    </diagnostics>
  </system.serviceModel>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
          switchValue="Error, Warning, ActivityTracing" propagateActivity="true" >
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging" switchValue="Error, Warning">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Temp\ServicesLog.svclog" />
    </sharedListeners>
  </system.diagnostics>
</configuration>
4

1 に答える 1

2

WCF サービスに serviceAuthorization 動作を追加してみてください - principalPermissionMode = always を使用します。

また、動作を「デフォルト」にしたい場合は、通常は name 属性を削除します。それ以外の場合は、サービス要素から明示的に参照する必要があります。

http://leastprivilege.com/2012/11/16/wcf-and-identity-in-net-4-5-external-authentication-with-ws-trust/を参照して ください。

于 2013-07-10T06:32:50.733 に答える