我将我的asp.net框架转换为asp.net核心。
我面临的一件事是在authorizationhandler中的Authentication上下文中保存查询数据。
在我的asp.net框架中,我已经完成了ASP.Net Framework中的AuthorizeAttribute:
public override void OnAuthorization(HttpActionContext actionContext)
{
// Retrieve email and password.
var accountEmail =
actionContext.Request.Headers.Where(
x =>
!string.IsNullOrEmpty(x.Key) &&
x.Key.Equals(HeaderFields.RequestAccountEmail))
.Select(x => x.Value.FirstOrDefault())
.FirstOrDefault();
// Retrieve account password.
var accountPassword =
actionContext.Request.Headers.Where(
x =>
!string.IsNullOrEmpty(x.Key) &&
x.Key.Equals(HeaderFields.RequestAccountPassword))
.Select(x => x.Value.FirstOrDefault()).FirstOrDefault();
// Invalid account name or password.
if (string.IsNullOrEmpty(accountEmail) || string.IsNullOrEmpty(accountPassword))
{
// Treat this request is unauthorized.
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new
{
Error = $"{Language.WarnAccountNotLogin}"
});
return;
}
// Find the hashed password from the original one.
var accountHashedPassword = RepositoryAccountExtended.FindMd5Password(accountPassword);
// Retrieve person whose properties match conditions.
var person = RepositoryAccountExtended.FindPerson(null, accountEmail, accountHashedPassword, null, null);
// No person has been found.
if (person == null)
{
// Treat this request is unauthorized.
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new
{
Error = $"{Language.WarnAccountNotLogin}"
});
return;
}
// Account has been disabled.
if ((StatusAccount) person.Status == StatusAccount.Inactive)
{
// Treat the login isn't successful because of disabled account.
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new
{
Error = $"{Language.WarnDisabledAccount}"
});
return;
}
// Account is still pending.
if ((StatusAccount) person.Status == StatusAccount.Pending)
{
// Treat the login isn't successful because of pending account.
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new
{
Error = $"{Language.WarnPendingAccount}"
});
return;
}
// Account role isn't enough to access the function.
if (!Roles.Any(x => x == person.Role))
{
// Role isn't valid. Tell the client the access is forbidden.
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden, new
{
Error = $"{Language.WarnForbiddenAccessMethod}"
});
}
// Store the requester information in action argument.
actionContext.ActionArguments[HeaderFields.Account] = person;
}
如您所见,我将查询数据(在这种情况下为Account)存储在actionContext中,稍后我可以在控制器中访问它。
我的问题是:如何在ASP.NET Core中实现相同的功能,因为我不想在每个AuthorizationHandler中查询我的数据库。
谢谢,
答案 0 :(得分:1)
如何在ASP.NET Core中实现相同的功能
首先,您需要一个身份验证中间件,对于您的情况,它可能是基本身份验证。对于Aspnet Core,没有内置的基本身份验证中间件。解决方案是here,或者您可以实现自己的身份验证中间件,如this。
我将查询数据(帐户 - 在这种情况下)存储在 actionContext,稍后我可以在Controllers中访问它。
我想到了两种可能的方式:
HttpContext.Items
要实现此功能,您可以在身份验证中间件之后使用ClaimsTransformation或自定义中间件。如果您使用自己的实现,也可以使用HandleAuthenticateAsync
方法。
<强>更新强>
保存查询数据似乎正确的地方是HandleAuthenticateAsync
。如果您使用@ blowdart的basic authentication解决方案,您的代码可能如下所示:
.....
await Options.Events.ValidateCredentials(validateCredentialsContext);
if (validateCredentialsContext.Ticket != null)
{
HttpContext.Items[HeaderFields.Account] = person; // assuming you retrive person before this
Logger.LogInformation($"Credentials validated for {username}");
return AuthenticateResult.Success(validateCredentialsContext.Ticket);
}