0

我已经设置了一个在 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>
4

1 回答 1

0

早些时候,当我查看PrincipalPermissionAttribute时,我走在了正确的轨道上。

由于我的一个误解, MSDN 上的这篇文章让我相信这个属性只适用于 windows 组和 windows 主体。

但是,我在serviceAuthorization 元素上发现了 principalPermissionMode 属性。根据 MSDN:

主体权限模式

设置用于在服务器上执行操作的主体。值包括以下内容:

  • 没有任何

  • 使用 Windows 组

  • 使用 AspNetRoles

  • 风俗

默认值为 UseWindowsGroups。

所以最后我的解决方案是更新 web.config 如下:

从 system.web 中删除了授权元素。这段代码拒绝任何未经身份验证的用户访问。

<system.web>
...
    <authorization>
        <deny users="?" />
    </authorization>
...
</system.web>

我还必须通过添加 principalPermissionMode="Custom" 来修改我的 serviceHostingEnvironment。这将允许我使用我的自定义主体而不是默认的 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 服务,而那些没有的用户则被拒之门外。完美运行。

于 2014-06-24T20:40:55.600 回答