#c# #asp.net #asp.net-web-api #asp.net-web-api-filters
#c# #asp.net #asp.net-web-api #asp.net-web-api-filters
Вопрос:
Я пытаюсь создать пользовательский фильтр аутентификации для ASP.NET Веб-API. Ниже приведен код для моего фильтра аутентификации
public class IDPAuthenticationFilter : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, "testUser"));
identity.AddClaim(new Claim(ClaimTypes.Role, "client"));
identity.AddClaim(new Claim("testUser"));
identity.AddClaim(new Claim("APP:USERID", "50123"));
var principal = new GenericPrincipal(identity, new string[] { });
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
base.OnAuthorization(actionContext);
}
}
Я настроил фильтр аутентификации глобально и подтвердил с помощью контрольной точки, что фильтр вызывается.
config.Filters.Add(new IDPAuthenticationFilter());
Проблема в том, что если я добавлю [System.Web.Http.Authorize]
атрибут к любому контроллеру, то получу ошибку 401 Unauthorized. Я могу получить доступ к имени пользователя, используя User.Identity.Name
в действии контроллера, но если я добавлю атрибут авторизации, я получу сообщение об ошибке. Есть ли что-то, чего мне не хватает.
Спасибо, что уделили вам время. Пожалуйста, добавьте комментарий на случай, если потребуется какая-либо другая информация.
Комментарии:
1. Могу я спросить, зачем вы добавляете атрибут authorize также, как и ваш?
2. IDPAuthenticationFilter предназначен для установки идентификатора, а атрибут авторизации гарантирует, что только аутентифицированные пользователи могут получить доступ к контроллеру.
3. @cl0ud В Web API фильтры аутентификации обрабатывают аутентификацию, но не авторизацию. Авторизация должна выполняться с помощью фильтра авторизации или внутри действия контроллера.
4. Причина, по которой я спрашиваю, заключается в том, что вы создаете,
IDPAuthenticationFilter
который наследуется отAuthorizationFilterAttribute
. Для меня это в принципе уже звучит некорректно, AuthorizationFilters предназначены для авторизации, как и следует из их названия.5. Спасибо, что указали на это, я внес некоторые изменения, и теперь я внедряю IAuthenticationFilter. При необходимости обновит вопрос.
Ответ №1:
Было несколько вещей, которые я делал неправильно. Сначала мне нужно было реализовать IAuthenticationFilter
вместо AuthorizationFilterAttribute
Во-вторых, способ, которым я устанавливал идентификатор, был неправильным. Ниже приведен код, который сработал у меня.
public class IDPAuthenticationFilter : Attribute, IAuthenticationFilter
{
public bool AllowMultiple => false;
public async Task AuthenticateAsync (HttpAuthenticationContext context, CancellationToken cancellationToken)
{
HttpRequestMessage request = context.Request;
AuthenticationHeaderValue authorization = request.Headers.Authorization;
if (authorization == null) {
return;
}
if (authorization.Scheme != "Bearer") {
return;
}
var claims = new List<Claim> ();
claims.Add (new Claim (ClaimTypes.Name, "testUser"));
claims.Add (new Claim (ClaimTypes.Role, "client"));
claims.Add (new Claim ("sub", "testUser"));
claims.Add (new Claim("APP:USERID", "50123"));
var identity = new ClaimsIdentity (claims, "Auth_Key");
var principal = new ClaimsPrincipal (new [] { identity });
context.Principal = principal;
HttpContext.Current.User = context.Principal;
Thread.CurrentPrincipal = context.Principal;
}
}