Как выполнить авторизацию на основе ролей для веб-API asp.net mvc 4

Я пытаюсь создать безопасный веб-API asp.net. Для этого я перешел по ссылке ниже

MessageHandler для токена

Итак, теперь каждому запросу API нужен токен, который я предоставляю в заголовке запроса, как показано ниже, например

public class TestController : Controller
{

    public string GetProducts()
    {
        Uri myUri = new Uri("http://localhost:420420/api/products");
        WebRequest myWebRequest = WebRequest.Create(myUri);

        myWebRequest.Method = "GET";
        myWebRequest.ContentType = "application/json";
        myWebRequest.Headers.Add("Authorization-Token", RSAClass.accessToken);

        using (WebResponse response = myWebRequest.GetResponse())
        {
            using (var responseStream = response.GetResponseStream())
            {
                var reader = new StreamReader(responseStream);
                return reader.ReadToEnd();
            }
        }
    }    
  }

Итак, теперь я могу делать каждый запрос API, проверять наличие токена в заголовке. Но как мне выполнить авторизацию, я имею в виду, как я могу запретить этому токену не иметь доступа к некоторым действиям в том же контроллере. Мне просто нужна идея. Надеюсь, я объяснил достаточно хорошо.

Изменить:

public class TestController : Controller
{
    public string GetProducts()
    {
        Uri myUri = new Uri("http://localhost:420420/api/products");         

        WebRequest myWebRequest = WebRequest.Create(myUri);

        myWebRequest.Method = "GET";
        myWebRequest.ContentType = "application/json";
        myWebRequest.Headers.Add("Authorization-Token", RSAClass.accessToken);

        **using (WebResponse response = myWebRequest.GetResponse())
        {
            using (var responseStream = response.GetResponseStream())
            {
                var reader = new StreamReader(responseStream);
                return reader.ReadToEnd();
            }
        }**
 }

Я делаю запрос к контроллеру «api» внутри вышеуказанного контроллера, используя веб-запрос (. Позже я изменю его на HttpClient ).В коде между****выше я получаю 404 страница не найдена дляmyWebRequest.GetResponse()

Ниже мой API-контроллер

public class ProductsController : ApiController
{

    TestModelContainer testModel = new TestModelContainer();

    [Authorize(Roles="Users")]
    public IEnumerable GetProducts()
    {
        IEnumerable products = (from prods in testModel.Products
                        select prods);
        return products;        
    }        
 }
}

Теперь в обработчике делегирования у меня есть следующий код

public class TokenValidationHandler : DelegatingHandler
{
    protected override Task SendAsync(HttpRequestMessage request,
     CancellationToken cancellationToken)
    {
        TestModelContainer testModel = new TestModelContainer();

        var token = "";
        try
        {

            if (request.Headers.Contains("Authorization-Token"))
            {

                token = request.Headers.GetValues("Authorization-Token").FirstOrDefault();

                if (String.IsNullOrEmpty(token))
                {
                    return Task.Factory.StartNew(() =>
                    {
                        return new HttpResponseMessage(HttpStatusCode.BadRequest)
                        {
                            Content = new StringContent("Missing Authorization-Token")
                        };
                    });
                }
            }
            else
            {
                return Task.Factory.StartNew(() =>
                {
                    return new HttpResponseMessage(HttpStatusCode.BadRequest)
                    {
                        Content = new StringContent("You need to include Authorization-Token " +
                        "header in your request")
                    };
                });
            }


            var decryptedToken = RSAClass.Decrypt(token);
            var foundUser =  (from user in testModel.Users
                                where user.Name == decryptedToken
                                select user).Any();              

            if (!foundUser)
                return Task.Factory.StartNew(() =>
                {
                    return new HttpResponseMessage(HttpStatusCode.Forbidden)
                    {
                        Content = new StringContent("Unauthorized User")
                    };
                });

      var identity = new GenericIdentity(decryptedToken);
              string[] roles = new string[] { "Users", "Testers" };

              var principal = new GenericPrincipal(identity, roles);
              Thread.CurrentPrincipal = principal;
        }
        catch (Exception ex)
        {
            return Task.Factory.StartNew(() =>
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent("Error encountered while attempting to process authorization token")
                };
            });
        }
        return base.SendAsync(request, cancellationToken);
    }

Ошибка 404 не возникает, если я удаляю атрибут Authorize из контроллера API, и тогда я могу получить к нему доступ.

Обновление (Я тоже верю в решение):

вот так вопрос решился

Я изменил метод TestController, как показано ниже, предложенный Дарином Димитровым

public class TestsController : Controller
{
    public ActionResult GetProducts()
    {
        var productsUrl = Url.RouteUrl("DefaultApi", new { httproute = "", controller = "products" }, "http");
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("Authorization-Token", RSAClass.accessToken);

         var products = client
              .GetAsync(productsUrl)
                .Result;

            if (products.StatusCode == HttpStatusCode.Unauthorized)
            {
                return Content("Sorry you are not authorized to perform this operation");
            }

            var prods = products.Content
               .ReadAsAsync>()
               .Result;

            return Json(prods, JsonRequestBehavior.AllowGet);
        }
    }

. Проблема была в том, что я не знал, как позвонить в API, благодаря Дарину за его большую поддержку (он тоже был очень быстр ).

Спасибо

10
задан CrazyNooB 20 August 2012 в 11:19
поделиться