我已经设置了一个在 ASP.NET 兼容模式下运行的 WCF 服务,这样我就可以利用我站点其他部分使用的 SSO 身份验证。SSO 基于 Jasig 的 CAS,我修改了 dotNetCasClient 以便它可以与 WCF 服务一起使用。这个想法是 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,但这不太可能,因为我通过 dotNetCasClient 而不是 windows 主体使用自定义主体。
请注意,如果我从 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>