C# MVC WebAPI 在成功登录后识别谁在发出请求

本文关键字:请求 识别 登录 MVC WebAPI 成功 | 更新日期: 2023-09-27 18:32:50

我想使用 MVC C# WebAPI。

在服务器级别了解谁向您发送请求的最佳方式是什么。例如,如果我收到一个登录请求并且它进行身份验证,WebAPI 是否应该返回服务器需要存储在某个位置以识别进一步调用的自定义令牌?

如果是这样,令牌是 WebAPI 已经嵌入的东西,还是我需要编写的东西?

服务器上存储该令牌的建议方法是什么?理想情况下,我不想使用任何会话。

另外,我

不太喜欢使用会员资格,原因很多,我不会在这里说明。

提前谢谢。

C# MVC WebAPI 在成功登录后识别谁在发出请求

进行身份验证的最佳方法是使用内置系统,但是由于您已经说过不喜欢它们,因此您只需要满足于不是最佳方法。

无论您是否使用成员资格,身份验证在 WebApi 中的工作方式与在 MVC 和 WebForms 中的工作方式相同。 您使用表单身份验证 Cookie,当请求传入时,框架会自动对其进行身份验证。 它存储在 HttpContext.Current.User.Identity 对象中。

至少自 .NET 2.0 以来,这并没有改变(太多),除了改进加密技术。

我创建了一个开源 MVC4 WebAPI 应用程序,它完全按照您描述的令牌身份验证执行操作。你可以在这里找到它 WebAPISoup.

这不是 asp.net 成员资格提供程序。使用自定义委派处理程序,它只需检查请求标头中是否有有效的应用 ID令牌值,并在允许请求继续之前根据数据库(首先是 EF5 代码)对其进行验证。

您可以通过在 mapHttpRoute 中设置处理程序来配置应用程序以全局处理此问题

WebApiConfig.cs

 config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: null,
            handler: HttpClientFactory.CreatePipeline(
                      new HttpControllerDispatcher(config),
                      new DelegatingHandler[] { new Pipeline.AuthMessageHandler() })
        );

AuthMessageHandler

public class AuthMessageHandler : DelegatingHandler
{
    private const string AppIdHeader = "AppId";
    private const string AppTokenHeader = "AppToken";
    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        IEnumerable<string> appIdValues;
        IEnumerable<string> appTokenValues;
        HttpStatusCode responseCode = HttpStatusCode.OK;
        Guid AppIdGuid;
        var DoesHaveAppId = request.Headers.TryGetValues(AppIdHeader, out appIdValues);
        var DoesHaveAppToken = request.Headers.TryGetValues(AppTokenHeader, out appTokenValues);
        //Forces Json to be request Body type
        request.Headers.Accept.Clear();
        request.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
        request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json");
        IPrincipal principal = null;
        if (DoesHaveAppId && DoesHaveAppToken)
        {
            if (Guid.TryParse(appIdValues.FirstOrDefault(), out AppIdGuid))
            {
                principal = ValidateAuthentication(AppIdGuid, appTokenValues.FirstOrDefault());
                if (principal != null) //Valid User
                {
                    System.Threading.Thread.CurrentPrincipal = principal;
                    if (IsAppOverLimit(AppIdGuid))
                    {
                        responseCode = (HttpStatusCode)429;
                    }
                }
                else//User failed to authenticate
                    responseCode = HttpStatusCode.Unauthorized;
            }
        }
        else//User didn't supply Key/Token
            responseCode = HttpStatusCode.Forbidden;

        return base.SendAsync(request, cancellationToken)
            .ContinueWith(task =>
            {
                var response = task.Result;
                if (responseCode == HttpStatusCode.OK)
                    return response;
                else
                    return request.CreateResponse(responseCode);
            });
    }
}

您可以在此处找到我创建的用于处理令牌身份验证请求的AuthMessageHandler