0

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>
4

1 に答える 1

0

先ほどPrincipalPermissionAttributeを見たとき、私は正しい軌道に乗っていました。

私の誤解により、MSDN のこの記事を読んで、この属性は Windows グループと Windows プリンシパルでのみ機能すると思い込んでしまいました。

しかし、 serviceAuthorization 要素の principalPermissionMode 属性を発見しました。MSDNによると:

principalPermissionMode

サーバー上で操作を実行するために使用されるプリンシパルを設定します。値には次のものがあります。

  • なし

  • UseWindowsGroups

  • UseAspNetRoles

  • カスタム

デフォルト値は 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 に答える