Код: Выделить всё
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();
}
}
На каждом сервере пользователь, на котором работает служба работает, не является членом 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);
}
Код: Выделить всё
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;
}
Подробнее здесь: https://stackoverflow.com/questions/787 ... is-correct
Мобильная версия