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>