2014-06-24 43 views
0

我已經設置了一個在ASP.NET兼容模式下運行的WCF服務,以便我可以利用我網站其餘部分使用的SSO身份驗證。 SSO基於Jasig的CAS,我修改了dotNetCasClient,以便它可以與WCF服務一起工作。這個想法是,dotNetCasClient http模塊攔截對服務的任何請求,並根據CAS提供的票據設置主體。無法在受保護的WCF服務上訪問WSDL

爲了得到這個工作,我不得不拒絕訪問所有匿名用戶:這一點的作品

<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,而不是窗戶校長工作的可能性較大。

請注意,如果我從我的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> 

回答

0

我是較早在正確的軌道上,當我在看PrincipalPermissionAttribute

由於我的錯誤理解,this MSDN上的文章讓我相信這個屬性只適用於windows組和windows主體。

但是我發現serviceAuthorization element上的principalPermissionMode屬性。根據MSDN:

principalPermissionMode

設置用於執行操作的服務器上的主體。包括以下屬性值:

  • UseWindowsGroups

  • UseAspNetRoles

  • 定製

默認值是UseWindowsGroups。

所以最終我的解決方案是更新網頁。配置如下:

從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票證用戶仍然能夠調用到我的網絡服務,而那些沒有被拒絕。完美的作品。