WCF “Basic” transport security issue when hosted in IIS

隐身守侯 提交于 2019-12-06 13:23:01

The issue appears to be when using Basic Authentication when hosting the service in IIS as IIS wants to handle the authentication.

This is discussed in this MSDN blog post

In the version of WCF that shipped with .Net Framework 3.0 we didn't support custom validators with transport level HTTP security. We received much feedback from the community that this was a highly desired feature, so I'm happy to say we added support for this scenario in the 3.5 release of the .Net Framework. Note that this is only supported under self hosted services.

There is a resolution as discussed in Allen Conway's Blog Post by implementing a custom authorisation manager derived from ServiceAuthorizationManager

CustomAuthorizationManager

public class CustomAuthorizationManager : ServiceAuthorizationManager 
{
    private const string UserName = "username";
    private const string Password = "password";

    protected override bool CheckAccessCore(OperationContext operationContext)
    {
        string authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];

        if ((authHeader != null) && (authHeader != string.Empty))
        {
            string[] svcCredentials = System.Text.ASCIIEncoding.ASCII
                                        .GetString(Convert.FromBase64String(authHeader.Substring(6)))
                                        .Split(':');

            var user = new { Name = svcCredentials[0], Password = svcCredentials[1] };

            if ((user.Name.Equals(UserName) && user.Password.Equals(Password)))
                return true;
            else
                return false;
        }
        else
        {
            WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"PsmProvider\"");
            throw new WebFaultException(HttpStatusCode.Unauthorized);
        }
    }

}

Config

  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="webInteropSecureBinding" allowCookies="false" maxBufferPoolSize="51200" maxBufferSize="51200" maxReceivedMessageSize="51200">
          <security mode="Transport"/>
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="PsmDataProvider.PsmProvider" behaviorConfiguration="SecureRest">
        <clear />
        <endpoint binding="webHttpBinding" bindingConfiguration="webInteropSecureBinding" 
                    name="PsmProvider" contract="PsmDataProvider.IPsmProvider" behaviorConfiguration="webHttpBehavior" />
        <endpoint address="mex" binding="mexHttpsBinding" name="mex" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:44300/PsmProvider/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SecureRest">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceAuthorization serviceAuthorizationManagerType="PsmDataProvider.Security.CustomAuthorizationManager, PsmDataProvider"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

Note

Also note a comment from Travich regarding the IIS / IIS Express configuration

Travich said... One thing to help other users. It was briefly stated, but something I overlooked... Turn off Basic Auth in IIS and remove tag from your webHttpBinding!

Works for me.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!