2014-06-24 45 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票证用户仍然能够调用到我的网络服务,而那些没有被拒绝。完美的作品。