Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Web Api的授权_C#_Asp.net_Asp.net Mvc_Asp.net Web Api - Fatal编程技术网

C# Web Api的授权

C# Web Api的授权,c#,asp.net,asp.net-mvc,asp.net-web-api,C#,Asp.net,Asp.net Mvc,Asp.net Web Api,我正在使用Visual studio 2013 mvc、webapi2和Odata开发一个RESTful WebApi 可以从移动客户端访问 我遵循下面给出的指导 现在我在授权方面遇到了一些困难。我希望api得到保护,并希望检查请求是否来自正确的用户 下面是我的客户端代码 <head> <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <scrip

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

可以从移动客户端访问

我遵循下面给出的指导

现在我在授权方面遇到了一些困难。我希望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));
    }
}

$(文档).ready(函数(){
$(“#发布”)。单击(函数(){
$.ajax({
键入:“获取”,
url:“http://localhost:21900/odata/Products(1)",
成功:功能(数据){
警报(数据);
},
错误:函数(XMLHttpRequest、textStatus、errorshown){
警报(文本状态);
}
});
});
});
和服务器端代码

<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));
    }
}
公共类产品控制器:ODataController
{
private ProductServiceContext db=new ProductServiceContext();
[可查询]
公共SingleResult GetProduct([FromODataUri]int-key)
{
返回SingleResult.Create(db.Products.Where(product=>product.ID==key));
}
}
我已经用[Authorize]尝试了上述方法,但对我来说效果不太好

任何帮助都将不胜感激


谢谢。

我还开发了一个web api,用户可以通过手机连接到它。 对于
身份验证
我使用.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

阅读

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

[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;
                }             

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

config.Filters.Add(new AuthorizeAttribute());
您还可以将其添加到特定的方法或类中,如下所示

[AuthorizeAttribute]
public class TestController : ApiController

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

您觉得
[Authorize]
不适合您吗?