在authenticationcontext asp.net核心中保存对象

时间:2016-10-30 13:02:09

标签: asp.net-core asp.net-core-webapi

我将我的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中查询我的数据库。

谢谢,

1 个答案:

答案 0 :(得分:1)

  

如何在ASP.NET Core中实现相同的功能

首先,您需要一个身份验证中间件,对于您的情况,它可能是基本身份验证。对于Aspnet Core,没有内置的基本身份验证中间件。解决方案是here,或者您可以实现自己的身份验证中间件,如this

  

我将查询数据(帐户 - 在这种情况下)存储在   actionContext,稍后我可以在Controllers中访问它。

我想到了两种可能的方式:

  1. 将参数添加到HttpContext.Items
  2. 向当前User.Identity添加声明
  3. 要实现此功能,您可以在身份验证中间件之后使用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);
                }