ASP.NET 互換モードで実行される WCF サービスをセットアップして、サイトの残りの部分で使用される SSO 認証を利用できるようにしました。SSO は Jasig の CAS に基づいており、WCF サービスで動作するように dotNetCasClient を変更しました。dotNetCasClient http モジュールが、サービスに対して行われたすべての要求をインターセプトし、CAS が提供するチケットに従ってプリンシパルをセットアップするという考え方です。
この作業を行うには、次の方法ですべての匿名ユーザーへのアクセスを拒否する必要がありました。
<system.web>
...
<authorization>
<deny users="?" />
</authorization>
...
</system.web>
この時点までのすべてが機能します。認証されていないユーザーが拒否されている間、認証されたユーザーは私のサービスを呼び出すことができます。問題は、.svc?wsdl を介して WSDL にアクセスできないことです。私は単に401.2を取得します。
サービスの残りの部分への匿名トラフィックを拒否しながら、WSDL への匿名トラフィックを許可する方法はありますか?
次のバリエーションを使用してみましたが、パスに ?wsdl があるのは好きではありません。
<location path=path/to/svc?wsdl>
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
また、匿名トラフィックを許可し、代わりにPrincipalPermissionAttributeを使用して遊んでみましたが、Windows プリンシパルではなく dotNetCasClient を介してカスタム プリンシパルを使用しているため、これはおそらく機能しません。
web.config から認証タグを削除すると、再び WSDL にアクセスできるようになりますが、SSO 認証が正しく機能しなくなることに注意してください。
これが私の完全なweb.configです
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="casServiceClientConfig" type="DotNetCasClient.Configuration.CasClientConfiguration, DotNetServiceCasClient" />
</configSections>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
<authentication mode="Forms">
<forms loginUrl="https://XXXX/cas/login" cookieless="UseCookies" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<casServiceClientConfig casServerLoginUrl="https://XXXX/cas/login"
casServerUrlPrefix="https://XXXX/cas/"
serverName="https://XXXX"
notAuthorizedUrl="~/NotAuthorized.aspx"
cookiesRequiredUrl="~/CookiesRequired.aspx"
redirectAfterValidation="true"
renew="false"
singleSignOut="true"
ticketValidatorName="Cas20"
serviceTicketManager="CacheServiceTicketManager"
proxyTicketManager="CacheProxyTicketManager"
/>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="DotNetCasClient" />
<remove name="PanelScheduler" />
<remove name="ScriptModule" />
<remove name="FormsAuthentication" />
<add name="DotNetServiceCasClient" type="DotNetCasClient.CasAuthenticationModule,DotNetServiceCasClient" />
</modules>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="XXXX" >
<endpoint contract="XXXX" address="" binding="customBinding" bindingConfiguration="nonSsLAuthBinding" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceAuthorization serviceAuthorizationManagerType="XXXX, XXXX">
<authorizationPolicies>
<add policyType="XXXX, XXXX" />
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<bindingElementExtensions>
<add name="nonSslAuthTransport" type="XXXX, XXXX"/>
</bindingElementExtensions>
</extensions>
<bindings>
<customBinding>
<binding name="nonSsLAuthBinding">
<textMessageEncoding messageVersion="Soap11" />
<nonSslAuthTransport authenticationScheme="None" allowCookies="true" keepAliveEnabled="true" />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>