У меня есть существующий REST API, разработанный с использованием ASP.NET WEB API 2, в котором авторизация обрабатывается путем сохранения всех подробностей имени контроллера и метода действия в xml-файле.
WebAPIAuthorization.xml:
<?xml version="1.0" encoding="utf-8" ?>
<WebApiAuthorizationSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<WebApiControllerAuthorizationSettings>
<WebApiControllerAuthorizationSetting>
<ControlerName>Profile</ControlerName>
<IsAuthorizationRequired>true</IsAuthorizationRequired>
<WebApiActionAuthorizationSettings>
<WebApiActionAuthorizationSetting>
<ActionName>GetProfile</ActionName>
<IsAuthorizationRequired>true</IsAuthorizationRequired>
</WebApiActionAuthorizationSetting>
</WebApiActionAuthorizationSettings>
</WebApiControllerAuthorizationSetting>
</WebApiControllerAuthorizationSettings>
</WebApiAuthorizationSettings>
Код:
public class CommonResponserHandler : DelegatingHandler
{
ICommonService _commonService = new CommonService();
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
string locale = string.Empty;
if (request.Headers.Contains(Constants.REQUEST_HEADER_ACEPT_LANGUAGE))
{
locale = request.Headers.GetValues(Constants.REQUEST_HEADER_ACEPT_LANGUAGE).First();
}
bool initialAuthorizationStatus = GetInitialAuthorization(request);
var response = await base.SendAsync(request, cancellationToken);
APIResult commonResponse;
if (response.TryGetContentValue<APIResult>(out commonResponse))
{
//populate common response here;
UpdateCommonResponse(request, response, commonResponse);
HttpResponseMessage newResponse;
bool authorizatinCheckResult = AssertAuthorization(initialAuthorizationStatus, request);
if (authorizatinCheckResult)
{
newResponse = request.CreateResponse(response.StatusCode, commonResponse);
}
else
{
var unAuthorisedResult = new APIResult{Authorized = false, UserMessage = Constants.Unauthorized, Locale = new Locale(_commonService.GetLanguageFromLocale(locale))};
newResponse = request.CreateResponse(HttpStatusCode.Unauthorized, unAuthorisedResult);
var jsonSerializerSettings = new JsonSerializerSettings{ContractResolver = new CamelCasePropertyNamesContractResolver()};
HttpContext.Current.Items["401message"] = JsonConvert.SerializeObject(unAuthorisedResult, Formatting.Indented, jsonSerializerSettings);
}
//Add headers from old response to new response
foreach (var header in response.Headers)
{
newResponse.Headers.Add(header.Key, header.Value);
}
return newResponse;
}
return response;
}
private bool GetInitialAuthorization(HttpRequestMessage request)
{
bool isAuthenticated = false;
try
{
string cookieId = string.Empty;
IEnumerable<CookieHeaderValue> cookies = request.Headers.GetCookies(Constants.COOKIE_BROWSER_NAME);
if (cookies.Any())
{
IEnumerable<CookieState> cookie = cookies.First().Cookies;
if (cookie.Any())
{
var cookieValue = cookie.FirstOrDefault(x => x.Name == Constants.COOKIE_BROWSER_NAME);
if (cookieValue != null)
cookieId = cookieValue.Value.ToLower();
}
}
isAuthenticated = _commonService.IsAuthorized(cookieId);
}
catch (Exception ex)
{
//log error
LogUtility.BuildExceptionMessage(ex);
}
return isAuthenticated;
}
private bool AssertAuthorization(bool initialAuthorizationStatus, HttpRequestMessage request)
{
bool authorizationCheckStatus = true;
//get controller name and action name.
var data = ((request.GetRouteData().Route.DataTokens as System.Web.Http.Routing.HttpRouteValueDictionary));
string actionName = ((System.Web.Http.Controllers.HttpActionDescriptor[])data["actions"])[0].ActionName;
string controllerName = ((System.Web.Http.Controllers.HttpActionDescriptor[])data["actions"])[0].ControllerDescriptor.ControllerName;
List<WebApiControllerAuthorizationSetting> webApiControllerAuthorizationSettings = WebApiAuthorizationSettings.GetWebApiAuthorizationSettings();
var controllerAuthorizationSetting = GetControllerSetting(webApiControllerAuthorizationSettings, controllerName);
if (controllerAuthorizationSetting != null)
{
bool isAuthenticationRequired = controllerAuthorizationSetting.IsAuthorizationRequired;
//if action level settings are available, then the controller settings will be overridden by action level settings
var actionAuthorizationSetting = GetActionSetting(controllerAuthorizationSetting, actionName);
if (actionAuthorizationSetting != null)
{
//check if the action is anonymous. if so, set the roles to anonymous.
isAuthenticationRequired = actionAuthorizationSetting.IsAuthorizationRequired;
}
if (isAuthenticationRequired)
{
if (!initialAuthorizationStatus)
{
authorizationCheckStatus = false;
}
}
}
return authorizationCheckStatus;
}
}
Любой запрос на / api / profile должен быть подтвержден для проверки авторизации.В GetInitialAuthorization () первоначальная авторизация выполняется на основе файла cookie, присутствующего в запросе, и оттуда выполняется еще одна проверка по методу: AssertAuthorization (initialAuthorizationStatus, request), где выполняется проверка файла WebAPIAuthorization.xml для обнаружения присутствия.контроллера и метода действия.
Для всех остальных конечных точек API REST авторизация отсутствует.
Я хочу реализовать это для полей GraphQL в тех же строках.
Может кто-нибудьпомогите с некоторыми рекомендациями по реализации этой политики авторизации.