Я пытаюсь создать безопасный веб-API asp.net. Для этого я перешел по ссылке ниже
Итак, теперь каждому запросу 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, благодаря Дарину за его большую поддержку (он тоже был очень быстр ).
Спасибо