c# – 如何使用Web Api中的Api密钥进行使用表单身份验证的服务身份验证

前端之家收集整理的这篇文章主要介绍了c# – 如何使用Web Api中的Api密钥进行使用表单身份验证的服务身份验证前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用MVC 4 Web Api,我希望在使用我的服务之前对用户进行身份验证.

我已经实现了一个授权消息处理程序,它运行得很好.

public class AuthorizationHandler : DelegatingHandler
{
    private readonly AuthenticationService _authenticationService = new AuthenticationService();

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
    {
        IEnumerable<string> apiKeyHeaderValues = null;
        if (request.Headers.TryGetValues("X-ApiKey",out apiKeyHeaderValues))
        {
            var apiKeyHeaderValue = apiKeyHeaderValues.First();

            // ... your authentication logic here ...
            var user = _authenticationService.GetUserByKey(new Guid(apiKeyHeaderValue));

            if (user != null)
            {

                var userId = user.Id;

                var userIdClaim = new Claim(ClaimTypes.SerialNumber,userId.ToString());
                var identity = new ClaimsIdentity(new[] { userIdClaim },"ApiKey");
                var principal = new ClaimsPrincipal(identity);

                Thread.CurrentPrincipal = principal;
            }
        }

        return base.SendAsync(request,cancellationToken);
    }
}

问题是,我使用表单身份验证.

[HttpPost]
    public ActionResult Login(UserModel model)
    {
        if (ModelState.IsValid)
        {
            var user = _authenticationService.Login(model);
            if (user != null)
            {
                // Add the api key to the HttpResponse???
            }
            return View(model);
        }

        return View(model);
    }

当我打电话给我的时候:

[Authorize]
public class TestController : ApiController
{
    public string GetLists()
    {
        return "Weee";
    }
}

处理程序找不到X-ApiKey标头.

有没有办法将用户的api密钥添加到http响应头并保持密钥,只要用户登录
有没有其他方法来实现此功能

解决方法

我找到了以下文章 http://www.asp.net/web-api/overview/working-with-http/http-cookies
使用它我配置我的AuthorizationHandler使用cookie:
public class AuthorizationHandler : DelegatingHandler
{
    private readonly IAuthenticationService _authenticationService = new AuthenticationService();

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
    {
        var cookie = request.Headers.GetCookies(Constants.ApiKey).FirstOrDefault();
        if (cookie != null)
        {
            var apiKey = cookie[Constants.ApiKey].Value;
            try
            {
                var guidKey = Guid.Parse(apiKey);

                var user = _authenticationService.GetUserByKey(guidKey);
                if (user != null)
                {

                    var userIdClaim = new Claim(ClaimTypes.Name,apiKey);
                    var identity = new ClaimsIdentity(new[] { userIdClaim },"ApiKey");
                    var principal = new ClaimsPrincipal(identity);

                    Thread.CurrentPrincipal = principal;

                }
            }
            catch (FormatException)
            {
            }
        }

        return base.SendAsync(request,cancellationToken);
    }
}

我配置了我的登录操作结果:

[HttpPost]
    public ActionResult Login(LoginModel model)
    {
        if (ModelState.IsValid)
        {
            var user = _authenticationService.Login(model);
            if (user != null)
            {
                _cookieHelper.SetCookie(user);

                return RedirectToAction("Index","Home");
            }

            ModelState.AddModelError("","Incorrect username or password");
            return View(model);
        }

        return View(model);
    }

在里面,我使用的是我创建的CookieHelper.它由一个界面组成:

public interface ICookieHelper
{
    void SetCookie(User user);

    void RemoveCookie();

    Guid GetUserId();
}

以及实现接口的类:

public class CookieHelper : ICookieHelper
{
    private readonly HttpContextBase _httpContext;

    public CookieHelper(HttpContextBase httpContext)
    {
        _httpContext = httpContext;
    }

    public void SetCookie(User user)
    {
        var cookie = new HttpCookie(Constants.ApiKey,user.UserId.ToString())
        {
            Expires = DateTime.UtcNow.AddDays(1)
        };

        _httpContext.Response.Cookies.Add(cookie);
    }

    public void RemoveCookie()
    {
        var cookie = _httpContext.Response.Cookies[Constants.ApiKey];
        if (cookie != null)
        {
            cookie.Expires = DateTime.UtcNow.AddDays(-1);
            _httpContext.Response.Cookies.Add(cookie);
        }
    }

    public Guid GetUserId()
    {
        var cookie = _httpContext.Request.Cookies[Constants.ApiKey];
        if (cookie != null && cookie.Value != null)
        {
            return Guid.Parse(cookie.Value);
        }

        return Guid.Empty;
    }
}

通过这个配置,现在我可以使用我的ApiControllers的Authorize属性

[Authorize]
public class TestController : ApiController
{
    public string Get()
    {
        return String.Empty;
    }
}

这意味着,如果用户没有登录.他无法访问我的api并收到401错误.此外,我可以在我的代码中的任何位置检索api密钥,我将其用作用户ID,这使得它非常干净和可读.

我不认为使用cookie是最好的解决方案,因为有些用户可能已经在浏览器中禁用了它们,但目前我还没有找到更好的方法来进行授权.

猜你在找的C#相关文章