Сначала не удалось выполнить авторизацию для запроса, а затем она верна.C#

Место общения программистов C#
Ответить
Anonymous
 Сначала не удалось выполнить авторизацию для запроса, а затем она верна.

Сообщение Anonymous »

В нашем бэкэнде есть несколько сервисов, которые должны взаимодействовать. До сих пор у них не было никакого разрешения. Таким образом, любой мог связаться с любой службой. Сейчас мы хотим ввести авторизацию во все сервисы. Поэтому мы написали следующий атрибут Authorize:

Код: Выделить всё

   public class BackendServiceAuthorizationAttribute : AuthorizeAttribute
{
private static readonly Lazy lazyUserAuthorizationProvider =
new Lazy(() => new UserAuthorizationProvider(), true);

private static UserAuthorizationProvider authorizationProvider => lazyUserAuthorizationProvider.Value;

public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext == null)
throw new ArgumentNullException(nameof(actionContext));

if (!IsAuthorized(actionContext))
{
EventLog.WriteEntry($"Backend-System", "Unauthorized request", EventLogEntryType.Warning);
HandleUnauthorizedRequest(actionContext);
}
else
{
EventLog.WriteEntry($"Backend-System", "Authorized request", EventLogEntryType.Warning);
}
}

protected override bool IsAuthorized(HttpActionContext actionContext)
{

if (actionContext == null)
throw new ArgumentNullException(nameof(actionContext));

return IsUserInGroup(actionContext) || IsUserAuthorized(actionContext);
}

private bool IsUserAuthorized(HttpActionContext actionContext)
{
bool isUserAuthenticated = false;

try
{
string currentUserId = DoClean(actionContext.RequestContext.Principal.Identity.Name);

isUserAuthenticated = authorizationProvider.IsUserAuthenticated(currentUserId);
}
catch (Exception e)
{
EventLog.WriteEntry($"Backend-System", $"Exception in IsUserAuthorized: {e}\nRequest-Principal: {actionContext.RequestContext.Principal}\nRequest: {actionContext.Request}");

}

return isUserAuthenticated;
}

private const string SoftwareAdmins = "Backend-Software-Administratoren";
private const string ServerAdmins = "Backend-Server-Administratoren";

private bool IsUserInGroup(HttpActionContext actionContext)
{
bool isInRole = false;
try
{
isInRole = actionContext.ControllerContext.RequestContext.Principal != null && (
actionContext.ControllerContext.RequestContext.Principal.IsInRole(SoftwareAdmins) ||
actionContext.ControllerContext.RequestContext.Principal.IsInRole(ServerAdmins));
}
catch (Exception e)
{
EventLog.WriteEntry($"Backend-System", $"Exception in IsUserInGroup: {e}");
}

return isInRole;
}

private static string DoClean(string userName)
{
string retval = userName;
if (retval.Contains("\\"))
{
string[] retsplits = retval.Split('\\');
retval = retsplits[retsplits.Length - 1];
}
if (retval.Contains("@"))
{
string[] retsplits = retval.Split('@');
retval = retsplits[0];
}
return retval.ToUpper();
}
}
UserAuthorizationProvider — это просто класс, в котором разрешенные идентификаторы пользователей инициализируются один раз.
На каждом сервере пользователь, на котором работает служба работает, не является членом SoftwareAdmins или ServerAdmins. Итак, мы используем метод IsUserAuthorized.
В журнале событий Windows на каждом сервере я вижу, что IsUserAuthorized выдает исключение, а затем я вижу запись из OnAuthorization, в которой говорится : Несанкционированный запрос. Следующая запись в журнале событий — «Авторизованный запрос»..
Поэтому я предполагаю, что атрибут Authorize вызывается несколько раз для запроса.
Мне интересно, смогу ли я избежать этого исключения?
В сообщении об исключении я вижу, что actionContext.RequestContext.Principal имеет значение null, поэтому вызов actionContext.RequestContext.Principal.Identity выдает исключение. Во втором запросе оно должно быть заполнено.
Все службы предоставляют самостоятельный REST-API, который размещается с использованием OWIN-Framework. Конфигурация Сервиса выглядит так:

Код: Выделить всё

public void Configuration(IAppBuilder appBuilder)
{

HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication | AuthenticationSchemes.Anonymous;

HttpConfiguration config = new HttpConfiguration();

config.DependencyResolver = controllerDependencyResolver;

config.MapHttpAttributeRoutes();

config.EnsureInitialized();

appBuilder.UseWebApi(config);
}
HttpClient для использования REST-API заключен в класс под названием «RestClient». Чтобы создать экземпляр RestClient, мы используем следующий код:

Код: Выделить всё

  private RestClient GetRestClient()
{

RestClientSettings restClientSettings = RestClientSettings.CreateDefault();
restClientSettings.UseDefaultCredentials = false;
ICredential cred = CredentialProvider.GetCredential(CredentialType.BackendSystem);
restClientSettings.Credentials = new NetworkCredential(cred.GetUserName(), cred.GetPwdSec(), "our_domain");
RestClient client = new RestClient($"{targetUrl}", restClientSettings);
return client;
}
Итак, мой вопрос: почему первая попытка авторизации завершается неудачей, а actionContext.RequestContext.Principal имеет значение null?

Подробнее здесь: https://stackoverflow.com/questions/787 ... is-correct
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»