Authorization of Web Api

本文关键字:Api Web of Authorization | 更新日期: 2024-10-20 10:15:21

我正在使用Visual studio 2013 mvc、webapi2和Odata、开发RESTful WebApi

其可以从移动客户端访问。

我正在遵循下面给出的教程

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api

现在我在授权方面遇到了一些困难。我希望api安全,并希望检查请求是否来自正确的用户。

以下是我的客户端代码

<head>
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    <script>
    $(document).ready(function() {
        $( "#post").click(function() {
        $.ajax({
                type: "GET",
                url: "http://localhost:21900/odata/Products(1)",
                success: function (data) {
                alert(data);
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                alert(textStatus);
                }
            });
        });
    });
    </script>
</head>
<body>
    <input type="submit" id="post" value="Post"/>
</body>

和服务器端代码

public class ProductsController : ODataController
{
    private ProductServiceContext db = new ProductServiceContext();

    [Queryable]
    public SingleResult<Product> GetProduct([FromODataUri] int key)
    {
        return SingleResult.Create(db.Products.Where(product => product.ID == key));
    }
}

我已经用[授权]尝试了上述操作,但对我来说无法正常工作

如有任何帮助,我们将不胜感激。

谢谢。

Authorization of Web Api

您必须创建如下新属性:-

[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class AuthorizeAttribute : AuthorizationFilterAttribute
    {       
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            base.OnAuthorization(actionContext);            
            ////check authentication and return if not authorized
            if (actionContext != null)
            {
                if (!WebSecurity.IsAuthenticated)
                {
                    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { RequestMessage = actionContext.ControllerContext.Request };
                     return;
                }             
            }
        }
    }

创建上述filter属性后,您可以将其添加到webapiconfig.cs文件中,如下所示,这样它将过滤您的所有请求。

config.Filters.Add(new AuthorizeAttribute());

您也可以添加它用于特定的方法或类,如下面的

[AuthorizeAttribute]
public class TestController : ApiController

有许多方法可以保护Web Api应用程序的安全。基本身份验证、OAuth、HMAC、API密钥、自定义令牌。在这里可以找到一个好的入门程序,它还提供了一个下载的示例应用程序。

我还开发了一个web api,用户可以通过手机连接到它。对于Authentication,我在.net中使用RSA。手机中的客户端,首先发送用户名和密码,然后创建一个令牌并将其发送给客户端。在接下来的请求中,客户端必须将这个令牌附加到请求头中,我得到这个令牌并从中提取用户名和密码

RSA加密:

public class ApiRSA
    {
        private static string privateKey = // Generate a private key
        private static string publicKey = // Generate a public key
        public static string Decrypt(string data)
        {
            var rsa = new RSACryptoServiceProvider();
            byte[] dataByte = Convert.FromBase64String(data);
            rsa.FromXmlString(privateKey);
            var decryptedByte = rsa.Decrypt(dataByte, false);
            return Encoding.Unicode.GetString(decryptedByte);
        }
        public static string Encrypt(string data)
        {
            var rsa = new RSACryptoServiceProvider();
            var dataByte = Encoding.Unicode.GetBytes(data);
            rsa.FromXmlString(publicKey);
            var encryptedByte = rsa.Encrypt(dataByte, false);
            return Convert.ToBase64String(encryptedByte);
        }
        public static void GeneraterPrivatePublicKey(out string privateKey, out string publicKey)
        {
            var csp = new RSACryptoServiceProvider(1024);
            var privKey = csp.ExportParameters(true);
            var pubKey = csp.ExportParameters(false);
            {
                var sw = new System.IO.StringWriter();
                var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
                xs.Serialize(sw, privKey);
                privateKey = sw.ToString();
            }
            {
                var sw = new System.IO.StringWriter();
                var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
                xs.Serialize(sw, pubKey);
                publicKey = sw.ToString();
            }
        }
    }

这个类将把用户名和密码加密成一个字符串(令牌)。在登录方法中,您可以检查用户名和密码,并根据用户名和密码生成一个令牌,然后返回此令牌。在任何进一步的请求中,客户端必须将此令牌附加到请求标头中。

为了检查进一步的请求,您可以使用自定义身份验证属性:

public interface IApiAuthenticationProvider
    {
        bool IsValid(string username, string password);
    }
public static class ApiAuthenticationEncrypter
{
    public static string Encrypt(string username, string password)
    {
        return ApiRSA.Encrypt(/*join username and password*/);
    }
    public static void Decrypt(string token, out string username, out string password)
    {
        var usernameAndPass = ApiRSA.Decrypt(token).Split(/*split username and password*/);
        username = usernameAndPass[0];
        password = usernameAndPass[1];
    }
}
public class ApiAuthenticationAttribute : ActionFilterAttribute
    {
        private IApiAuthenticationProvider AuthenticationProvider { get; set; }
        public ApiAuthenticationAttribute(Type apiAuthenticationType)
        {
            Debug.Assert(typeof(IApiAuthenticationProvider).IsAssignableFrom(apiAuthenticationType));
            AuthenticationProvider = (IApiAuthenticationProvider) Activator.CreateInstance(apiAuthenticationType);
        }
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            Debug.Assert(AuthenticationProvider != null);
            Object httpContextBase;
            bool isValid = actionContext.Request.Properties.TryGetValue("MS_HttpContext", out httpContextBase);
            bool isLocal = isValid && ((HttpContextBase)httpContextBase).Request.IsLocal;
            if (isLocal)
            {
                base.OnActionExecuting(actionContext);
                return;
            }

            //// == Only Https request ==
            //if (!String.Equals(actionContext.Request.RequestUri.Scheme, "https", StringComparison.OrdinalIgnoreCase))
            //{
            //    actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
            //    {
            //        Content = new StringContent("HTTPS Required")
            //    };
            //    return;
            //}
            // == Try to get Token ==
            string token;
            try
            {
                token = actionContext.Request.Headers.GetValues("AuthenticationToken").First();
            }
            catch (Exception)
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    Content = new StringContent("AuthenticationToken not found"),
                };
                return;
            }
            // == Validate using validator provider ==
            try
            {
                string username;
                string password;
                ApiAuthenticationEncrypter.Decrypt(token, out username, out password);
                if (AuthenticationProvider.IsValid(username, password))
                    base.OnActionExecuting(actionContext);
                else
                    throw new Exception();
            }
            catch (Exception)
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
                {
                    Content = new StringContent("Invalid UserName or Password")
                };
                return;
            }
        }
    }

并通过IApiAuthenticationProvider:的具体类型使用此属性

[ApiAuthentication(typeof (Concrete Type of IApiAuthenticationProvider))]
public class SomeController: ApiController

阅读此处