【问题标题】:Save object in authenticationcontext asp.net core在 authenticationcontext asp.net core 中保存对象
【发布时间】:2016-10-30 22:06:52
【问题描述】:

我正在将我的 asp.net 框架转换为 asp.net 核心。

我面临的一件事是将查询数据保存在授权处理程序的身份验证上下文中。

在我的 asp.net 框架中,我已经在 ASP.Net 框架中处理了我的 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;
        }

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

我的问题是:如何在 ASP.NET Core 中实现相同的功能,因为我不想在每个 AuthorizationHandler 中查询我的数据库。

谢谢,

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    1. 将参数添加到HttpContext.Items
    2. 向当前 User.Identity 添加声明

    要实现这一点,您可以在身份验证中间件之后使用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);
                }
    

    【讨论】:

    • 感谢您一路前行。我想我选择 HttpContext.Items 是因为在我的应用程序中使用了 JWT :)
    猜你喜欢
    • 1970-01-01
    • 2023-02-04
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2020-07-14
    • 1970-01-01
    • 2016-06-29
    相关资源
    最近更新 更多