如何在Web Service中实现身份验证

时间:2012-03-24 05:46:58

标签: c# .net web-services authentication iis-6

我将在c#中创建一个Web服务.Client将发送用户名和密码。我想在访问Web方法之前验证用户,即在IIS级别。是否可以在c#中创建一个过滤器。任何人都可以共享代码或链接。用户详细信息存储在MSSQL数据库中[我想验证这样的用户是否存在于Database.If用户不存在,那么我想阻止请求,那里有自己。目的是避免在每种网络方法中验证用户]。

1 个答案:

答案 0 :(得分:5)

我建议构建基于REST的Web服务,并通过API密钥而不是用户名和密码发送。

查看:REST GET requests, verbs and apikey

然后只使用基于Google REST的ASP.NET Web服务来获取有关如何完成它的大量教程。

已更新以显示实施

注意:我找不到原始页面,但此代码基于某处的示例。

第1步 - 编辑web.config

将其插入system.serviceModel部分。

<behaviors>
  <serviceBehaviors>
    <clear />
    <behavior>
      <!-- This behavior enables API Key Verification -->
      <serviceAuthorization serviceAuthorizationManagerType="API.APIKeyAuthorization, API" />
      <serviceMetadata httpGetEnabled="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

第2步 - 创建API授权类

更改IsValidAPI键中的代码以适合您的实际情况。你可以看到我去了一个函数来测试API密钥是否有效。

namespace API
{
public class APIKeyAuthorization : ServiceAuthorizationManager
{
    public const string APIKEY = "APIKey";
    public const string APIKEYLIST = "APIKeyList";

    protected override bool CheckAccessCore(OperationContext operationContext)
    {
        return IsValidAPIKey(operationContext);
    }

    public bool IsValidAPIKey(OperationContext operationContext)
    {
        // if verification is disabled, return true
        if (Global.APIKeyVerification == false)
            return true;

        string key = GetAPIKey(operationContext);

        // Convert the string into a Guid and validate it
        if (BusinessLogic.User.ApiKey.Exists(key))
        {
            return true;
        }
        else
        {
            // Send back an HTML reply
            CreateErrorReply(operationContext, key);
            return false;
        }
    }

    public string GetAPIKey(OperationContext operationContext)
    {
        // Get the request message
        var request = operationContext.RequestContext.RequestMessage;

        // Get the HTTP Request
        var requestProp = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];

        // Get the query string
        NameValueCollection queryParams = HttpUtility.ParseQueryString(requestProp.QueryString);

        // Return the API key (if present, null if not)
        return queryParams[APIKEY];
    }

    private static void CreateErrorReply(OperationContext operationContext, string key)
    {
        // The error message is padded so that IE shows the response by default
        using (var sr = new StringReader("<?xml version=\"1.0\" encoding=\"utf-8\"?>" + APIErrorHTML))
        {
            XElement response = XElement.Load(sr);
            using (Message reply = Message.CreateMessage(MessageVersion.None, null, response))
            {
                HttpResponseMessageProperty responseProp = new HttpResponseMessageProperty() { StatusCode = HttpStatusCode.Unauthorized, StatusDescription = String.Format("'{0}' is an invalid API key", key) };
                responseProp.Headers[HttpResponseHeader.ContentType] = "text/html";
                reply.Properties[HttpResponseMessageProperty.Name] = responseProp;
                operationContext.RequestContext.Reply(reply);
                // set the request context to null to terminate processing of this request
                operationContext.RequestContext = null;
            }
        }
    }

    public const string APIErrorHTML = @"
<html>
<head>
    <title>Request Error - No API Key</title>
    <style type=""text/css"">
        body
        {
            font-family: Verdana;
            font-size: x-large;
        }
    </style>
</head>
<body>
    <h1>
        Request Error
    </h1>
    <p>
        A valid API key needs to be included using the apikey query string parameter
    </p>
</body>
</html>
";
    }
}

API授权在您点击Web方法之前完成。但是,此示例显示API密钥作为查询字符串传递。请按照上面链接中的更多示例将其更改为通过HTTP标头发送。一个更干净的方法,它不会弄乱你的URL。但这一切都取决于你的要求。

<强>更新 实际上我刚刚遇到过这样的问题:Microsoft ASP.NET Web API - http://www.asp.net/web-api

试试:)