一个WCF REST服务是否支持基本认证和Windows认证?

3
我有一个自托管的REST WCF Windows服务。我已经让服务支持基本认证,但我也想支持客户端使用Windows身份验证。我需要在不同的端口上拥有单独的终结点吗?
更新:我已经在WCF 4.0上实现了类似的功能。以下是代码,我现在遇到的问题是,我只能获得NTLM工作,这需要用户输入其凭据,这使使用Windows Auth无法发挥任何好处。
我仍然不确定如何在不要求用户再次输入密码的情况下启用Windows身份验证。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.IdentityModel.Selectors;

namespace BasicAndNegotiateAuth
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri newUri = new Uri(new Uri("http://localhost/"), "/");
            WebServiceHost webHost = new WebServiceHost(typeof(HelloWorldService), newUri);

            // TransportCredentialOnly means we can use http
            WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.Transport);
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic | HttpClientCredentialType.Ntlm;

            ServiceEndpoint ep = webHost.AddServiceEndpoint(typeof(IHelloWorld), binding, newUri);

            WebHttpBehavior wb = new WebHttpBehavior();                
            ep.EndpointBehaviors.Add(wb);
            ep.Behaviors.Add(new WebHttpCors.CorsSupportBehavior());

            //ServiceAuthenticationBehavior sab = null;
            //sab = webHost.Description.Behaviors.Find<ServiceAuthenticationBehavior>();
            //if (sab == null)
            //{
            //    sab = new ServiceAuthenticationBehavior();
            //    sab.AuthenticationSchemes = AuthenticationSchemes.Basic | AuthenticationSchemes.IntegratedWindowsAuthentication;
            //    host.Description.Behaviors.Add(sab);
            //}
            webHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
            webHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();

            webHost.Open();
            Console.ReadLine();
        }
    }

    public class CustomUserNameValidator: UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            int i = 1;
        }
    }

    [ServiceContract]
    public interface IHelloWorld
    {
        [System.ServiceModel.OperationContract]
        [System.ServiceModel.Web.WebGet(
            UriTemplate = "/",
            ResponseFormat = WebMessageFormat.Json)]
        string GetHello();
    }

    public class HelloWorldService : IHelloWorld
    {
        public string GetHello()
        {
            ServiceSecurityContext ssc = ServiceSecurityContext.Current;
            return "Hello World";
        }
    }
}
1个回答

2
在.NET 4.5中,你可以在WCF的单个终结点上支持多种身份验证方案。
以下是自托管服务代码示例:
ServiceAuthenticationBehavior sab = null;
sab = serviceHost.Description.Behaviors.Find<ServiceAuthenticationBehavior>();
if (sab == null)
{
    sab = new ServiceAuthenticationBehavior();
    sab.AuthenticationSchemes = AuthenticationSchemes.Basic | 
           AuthenticationSchemes.Negotiate | AuthenticationSchemes.Digest;
    serviceHost.Description.Behaviors.Add(sab);
}
else
{
     sab.AuthenticationSchemes = AuthenticationSchemes.Basic | 
           AuthenticationSchemes.Negotiate | AuthenticationSchemes.Digest;
}

另外,您可以像这样在配置文件中设置:

<behaviors>
    <serviceBehaviors>
      <behavior name="limitedAuthBehavior">
        <serviceAuthenticationManager authenticationSchemes=
                                             "Negotiate, Digest, Basic"/>
        <!-- ... -->
      </behavior>
   </serviceBehaviors>
</behaviors>

然后在绑定设置中指定InheritedFromHost,如下所示:

<bindings>
   <basicHttpBinding>
      <binding name="secureBinding">
        <security mode="Transport">
          <transport clientCredentialType="InheritedFromHost" />
        </security>
      </binding>
   </basicHttpBinding>
</bindings>

请查看MSDN上的这篇文章:在WCF中使用多个身份验证方案


这只在4.5中有效吗?另外,在您提供的示例中,Windows身份验证是哪种身份验证方案不太清楚? - bpeikes
AuthenticationSchemes.IntegratedWindowsAuthentication 是您设置 Windows 身份验证 所需的内容。是的,这仅适用于 .NET 4.5 及更高版本。 - Derek W
如果我们放置AuthenticationSchemes.Basic和AuthenticationSchemes.IntegratedWindowsAuthentication,哪一个会首先尝试? - bpeikes
(2)对于使用基本身份验证的自托管服务 - 它由UserNamePasswordValidator处理。类似于为其他绑定指定ClientCredentialTypeUserName时。 - Derek W
1
这有点超出了这个问题的范围。但是在SO上有一些现有的问题可以解决这个问题:https://dev59.com/HWgu5IYBdhLWcg3wHjl7和https://dev59.com/J0nSa4cB1Zd3GeqPKxjw。 - Derek W
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接