如何通过自托管WCF REST API对签名用户进行身份验证

本文关键字:用户 身份验证 API 何通过 REST WCF | 更新日期: 2023-09-27 18:24:41

我有一个自托管的WCF RESTful API,它公开了一些功能,我不希望向未经授权的用户公开这些功能。所有管理员都必须使用自定义ASP.NET成员身份提供程序登录才能调用REST API。目前我只是发送一个API密钥,这是不安全的,因为它可以被所有人看到。对REST API的所有调用都是通过jQuery完成的。我没有使用TLS/SSL或其他传输安全机制。所有REST API调用都是针对同一个服务器/域进行的,因此没有跨域调用或JSONP的东西

我的问题是,在我的情况下,保护我的REST API的最佳实践是什么?也许我应该使用OAuth来实现这一点——我读到的关于OAuth的信息越多,它就越不适合我使用jQuery的场景。

IVeraCMS.cs:

[ServiceContract]
public interface IVeraCMS {
    [OperationContract]
    [WebInvoke(Method = "GET",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json)]
    string PerformanceCounter(string API_Key);
}

VeraCMS.cs:

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall,
         IncludeExceptionDetailInFaults = false, MaxItemsInObjectGraph = 1000)]
    public class VeraCMS : IVeraCMS
    {
        public string PerformanceCounter(string API_Key)
        {
            if (ConfigurationManager.AppSettings["API_key"] != API_Key)
                throw new SecurityException("Access denied");
            var procPercentage = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            procPercentage.NextValue();
            var memPercentage = new PerformanceCounter("Memory", "Available MBytes");
            memPercentage.NextValue();
            const int samplingIntervalMs = 100;
            Thread.Sleep(samplingIntervalMs);
            var json = "{" + String.Format("'"ProcTime'":'"{0}%'",'"AvailMemory'":'"{1}MB'"" ,
                procPercentage.NextValue().ToString(), memPercentage.NextValue().ToString()
                ) + "}";
            return json;
        }
    }
}

Web.config:

  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="VeraWAF.WebPages.Interfaces.VeraCMS.Endpoint.Binding" maxReceivedMessageSize="4096" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="VeraWAF.WebPages.Interfaces.VeraCMS.Service.Behavior"
               name="VeraWAF.WebPages.Interfaces.VeraCMS">
        <endpoint address="" behaviorConfiguration="VeraWAF.WebPages.Interfaces.VeraCMS.Endpoint.Behavior"
          binding="webHttpBinding" bindingConfiguration="VeraWAF.WebPages.Interfaces.VeraCMS.Endpoint.Binding"
          contract="VeraWAF.WebPages.Interfaces.IVeraCMS" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="VeraWAF.WebPages.Interfaces.VeraCMS.Endpoint.Behavior">
          <webHttp defaultOutgoingResponseFormat="Json" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="VeraWAF.WebPages.Interfaces.VeraCMS.Service.Behavior">
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

如何通过自托管WCF REST API对签名用户进行身份验证

您可以像这样进行基本的HTTP身份验证:

WebServiceHost secureHost
secureHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
secureHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new ClientValidator(username, password);

// Need to reference System.IdentityModel
public class ClientValidator : UserNamePasswordValidator
{
    private readonly string _password;
    private readonly string _username;
    public ClientValidator(string username, string password)
    {
        _password = password;
        _username = username;
    }
    public override void Validate(string userName, string password)
    {
        if (userName != _username || (password != _password))
        {
            WebFaultException rejectEx = new WebFaultException(HttpStatusCode.Unauthorized);
            rejectEx.Data.Add("HttpStatusCode", rejectEx.StatusCode);
            throw rejectEx;
        }
    }
}

请记住,如果您不使用SSL,您的用户名和密码可以很容易地被嗅探。您可以更改Validate方法以从DB或其他服务获取用户名和密码。