无法访问受保护的WCF服务上的WSDL
本文关键字:服务 WSDL WCF 访问 受保护 | 更新日期: 2023-09-27 18:10:10
我已经设置了一个在ASP中运行的WCF服务。. NET兼容模式,这样我就可以利用站点其他部分使用的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主体。
注意,如果我从我的网页中删除授权标签。config I再次可以访问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>
当我查看PrincipalPermissionAttribute时,我在正确的轨道上。
由于我的误解,MSDN上的这篇文章让我相信这个属性只适用于windows组和windows主体。
然而,我在serviceAuthorization元素上发现了principalPermissionMode属性。根据MSDN:
principalPermissionMode
设置用于在服务器上执行操作的主体。取值包括:
没有
UseWindowsGroups
UseAspNetRoles
自定义
默认值是UseWindowsGroups。
所以最后我的解决方案是更新网页。配置如下:
从system.web删除了authorization元素。这段代码拒绝任何未经身份验证的用户访问。
<system.web>
...
<authorization>
<deny users="?" />
</authorization>
...
</system.web>
我还必须修改我的serviceHostingEnvironment添加principalPermissionMode="Custom"。这将允许我使用我的自定义主体,而不是默认的windows组。
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpGetUrl="WSDL" />
<serviceAuthorization serviceAuthorizationManagerType="XXXX, XXXX" principalPermissionMode="Custom">
<authorizationPolicies>
<add policyType="XXXX, XXXX" />
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
...
<system.serviceModel>
之后,我必须在我的服务方法中添加PrincipalPermissionAttribute,如下所示:
[PrincipalPermission(SecurityAction.Demand, Authenticated=true, Unrestricted=true)]
public string GetData(string data)
{
string primaryIdentity;
if (ServiceSecurityContext.Current != null)
primaryIdentity = ServiceSecurityContext.Current.PrimaryIdentity.Name;
else
primaryIdentity = "Not found";
int cookies = 0;
var request = HttpContext.Current.Request;
if (request != null && request.Cookies.Count > 0)
cookies = request.Cookies.Count;
return string.Format("You passed in: {0} - Primary Identity of Authenticated User: {1} - Found {2} cookies", data, primaryIdentity, cookies);
}
我现在可以在没有身份验证的情况下访问我的WSDL,但是拥有SSO票证的用户仍然可以调用我的web服务,而那些没有的用户则被拒绝。完美的工作。