Начал изучать web api, дошёл до аутентификации пользователей и тут возник вопрос. Создаю отдельный простой фильтр аутентификации, по примерам, наследуемый от IAuthenticationFilter. В методе AuthenticateAsync прописываю следующее:
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
context.Principal = null;
AuthenticationHeaderValue authentication = context.Request.Headers.Authorization;
if (authentication != null)
{
if (authentication.Scheme == "Basic")
{
string[] authData = Encoding.ASCII.GetString(Convert.FromBase64String(authentication.Parameter)).Split(':');
if (authData[0] == "testuser" && authData[1] == "Pass1word")
{
context.Principal = new GenericPrincipal(new GenericIdentity(authData[0]), new[] { "user" });
}
}
}
if (context.Principal == null)
{
context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[] { new AuthenticationHeaderValue("Basic") }, context.Request);
}
return Task.FromResult<object>(null);
}
Далее в WebApiConfig.cs добавляю фильтр:
config.Filters.Add(new CustomAuthenticationFilter());
А в самом контроллере указываю:
[Authorize(Roles ="user")]
И всё бы ничего, даже работает, к контроллеру без аутентификации не пускает. Но, если создать другой контроллер и ему указать
[AllowAnonymous]
то при вызове этого контроллера всё также необходима аутентификация.
Как быть? Помогите разобраться.
Вы добавили фильтр, который применяется для всех контроллеров глобально и не пускает вас без аутентификации. Что хотели - то и получили...
Уберите создание UnauthorizedResult из AuthenticateAsync и реализуйте метод ChallengeAsync как рекомендуют в статье из документации:
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
var challenge = new AuthenticationHeaderValue("Basic");
context.Result = new AddChallengeOnUnauthorizedResult(challenge, context.Result);
return Task.FromResult(0);
}
public class AddChallengeOnUnauthorizedResult : IHttpActionResult
{
public AddChallengeOnUnauthorizedResult(AuthenticationHeaderValue challenge, IHttpActionResult innerResult)
{
Challenge = challenge;
InnerResult = innerResult;
}
public AuthenticationHeaderValue Challenge { get; private set; }
public IHttpActionResult InnerResult { get; private set; }
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage response = await InnerResult.ExecuteAsync(cancellationToken);
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
// Only add one challenge per authentication scheme.
if (!response.Headers.WwwAuthenticate.Any((h) => h.Scheme == Challenge.Scheme))
{
response.Headers.WwwAuthenticate.Add(Challenge);
}
}
return response;
}
}
Общая идея - не выдавать 401 всем безусловно - а дождаться пока отработает фильтр авторизации и только требовать логин и пароль только при ошибке доступа.
Я как то встречал возможность выполнить код, вклинившись в работающий ThreadНо не могу вспомнить как это делалось
Подскажите пожалуйста пример кода, чтобы при нажатии кнопки изменялся горизонтальный масштаб, например листбокса listbox1 от 0 до 1, то есть чтобы...