带有自定义身份验证的.NET 4.5 WCF rest



首先,我是WCF的新手。我使用WCF创建了一个REST Web服务。它只有一个检索产品列表的操作(json格式)。这是使用jquery从web调用的。它工作得很好。

现在,我需要的是向Web服务添加一个自定义身份验证。是否可以将其添加到webHttpBinding?我添加了验证:

public class ServiceAuthenticator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        if (null == userName || null == password)
        {
            throw new ArgumentNullException();
        }
        if (userName != "testuser")
        {
            throw new SecurityTokenException("Unknown Username or Password");
        }
    }
}

我试图更改web.config以使其工作,但我做不到。

这是我在没有自定义身份验证的情况下工作的web.config:

  <system.serviceModel>
<bindings>
  <webHttpBinding>
    <binding crossDomainScriptAccessEnabled="true">
    </binding>
  </webHttpBinding>
</bindings>
<behaviors>
  <endpointBehaviors>
    <behavior name="WCFEndPointBehavior">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyRestService.ServiceAuthenticator, MyRestService" />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
  <service name="MyRestService.ProductRESTService" behaviorConfiguration="ServiceBehavior">
    <endpoint address=""
              behaviorConfiguration="WCFEndPointBehavior"
              binding="webHttpBinding"
              contract="MyRestService.IProductRESTService">
      <identity>
        <dns
        value="localhost"/>
      </identity>          
    </endpoint>
  </service>
</services>

以下是调用ws的jquery:

$("#myButton").click(function () {
    var artistURL = "http://localhost:56866/ProductRESTService.svc/GetProductList/";
    var returnData = "";
    $.ajax({
        cache: false,
        type: "GET",
        async: false,
        processData: true,
        data: "",
        url: artistURL,
        contentType: "application/json; charset=utf-8",
        dataType: "jsonp",
        beforeSend: function (xhr) {
            xhr.setRequestHeader("Authorization", "Basic " + btoa("testuser:123456789"));
        },
        error: function (request, status, error) { alert("Error"); },
        success: function (data, status, jqXHR) {
            $("div#myOutput").html(" ");
            returnData = "<table style='font-size:12pt;font-family:sans-serif'><tr><th>Product</th><th></th></tr>";
            for (prop in data) {
                if (!data.hasOwnProperty(prop)) { continue; }
                if (data[prop] != null) {
                    for (var i = 0; i < data[prop].length; i++) {
                        returnData += "<tr><td>" + data[prop][i]["ProductId"]
                                   + " " + data[prop][i]["Name"] + "</td><td align='right'>"
                                   + data[prop][i]["CategoryName"] + "</td></tr>";
                    }
                }
            }
            returnData = returnData + "</table>";
            $("div#myOutput").html(returnData);
        }
    });
    return (false);
});

当我执行此操作时,它工作正常,但从未到达自定义验证器。我的web.config中缺少什么吗?如何将自定义身份验证应用于此类Web服务?

我正在使用:.NET Framework 4.5带有VS2012 的IIS Express

提前感谢!

编辑

身份验证由IIS执行,这就是为什么没有触发自定义验证的原因。有一些解决办法:

  1. 自托管服务
  2. ISS Hosted使用ServiceAuthorizationManager执行自定义身份验证(它应该用于授权,没有身份验证,但这是我找到的唯一方法)。这里有更多信息:使用webHttpBinding对IIS托管的REST服务进行基本身份验证

如果有人有其他解决方法。。。你可以自由评论!我希望这能有所帮助。

我知道我参加聚会迟到了,但我只需要用我自己的一个服务解决这个问题,IIS盗用了身份验证,而且不清楚发生了什么或如何解决,所以下面是一个循序渐进的步骤:

首先创建一个执行身份验证的类:

您的类必须派生自System.IdentityModel.Selectors(System.Identity Model)命名空间中的UserNamePasswordValidator:

using System.IdentityModel.Selectors;
namespace MyProject
{
    public class CustomUserNameValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (username != "Bob" || password != "Letmein")
                through new SecurityTokenException("If you're name's not Bob, you're not coming in!")
        }
    }
}

下一步您需要为您的开发端点提供SSL证书:

有许多教程可用于生成您自己的自签名证书。我使用了这个教程,但有很多,你可能会找到其他更简单的方法。由于浏览器对自签名证书的限制,我使用直接自签名证书成功率有限。为了避免这种情况,我使用相同的过程创建了根证书颁发机构,然后使用我的RCA创建了一个签名证书。这似乎满足了浏览器的限制,并消除了任何警告。[严格地说,这很可能是超出需求的,但警告让我很困扰。]

创建SSL证书后,请使用certificates.msc将其注册到证书(本地计算机)\个人\证书中。

将IIS端点与端口443(或您希望的任何端口)绑定,以获得您刚刚创建的证书。

接下来,您需要定义一个服务行为:

您的服务行为必须包含对凭据验证器和SSL证书的引用。

    <behavior name="MyCustomCredentialBehavior">
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyProject.MyCustomCredentialValidator, MyAssembly" />
        <serviceCertificate findValue="CN=*.dev.myco.com"                             
                            x509FindType="FindBySubjectDistinguishedName" 
                            storeLocation="LocalMachine" />
      </serviceCredentials>
      <serviceMetadata httpGetEnabled="true" />
    </behavior>

您可以使用可分辨名称或指纹来引用您的证书。在我的例子中,我使用了创建证书时选择的可分辨名称。如果你使用指纹,复制/粘贴指纹时要小心,因为序列开头有一个字节标记字符,会破坏你的引用,所以你的应用程序找不到它。手动复制序列比沮丧更容易,或者通过其他明文编辑器(如记事本)复制,可以去掉未打印的字符。

最后,您需要您的服务配置来参考您的服务行为:

  <service name="MySecureService"
           behaviorConfiguration="MyCustomCredentialBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="https://myservice.com/mysecureservice/" />
      </baseAddresses>
    </host>
    <endpoint name="MySecureServiceEndpoint" 
              binding="webHttpBinding" 
              contract="IMySecureService" />
  </service>

如果我没有记错的话,这应该是你所需要的一切。

相关内容

  • 没有找到相关文章

最新更新