繁体   English   中英

使用Owin在Asp.Net Web Api中同时使用OAuth和基本身份验证

[英]Using both OAuth and Basic Auth in Asp.Net Web Api with Owin

我已经根据这些博客文章在Web Api项目中实现了OAuth身份验证

它工作良好,包括刷新令牌逻辑。

我想为计划的作业的几个调用添加基本身份验证的选项。

我尝试添加基本身份验证解决方案作为中间件,但是我仍然收到401询问Bearer令牌。

我可以通过从这些api调用中删除[Authorize]属性,并在代码中手动检查用户是否通过身份验证来解决问题,以使其正常工作。

是否可以使用OWin支持基本身份验证和OAuth身份验证?

如何使用属性[OverrideAuthentication]为要实现基本身份验证的操作或控制器分配属性,然后创建自定义身份验证过滤器属性,该属性继承自Attribute, IAuthenticationFilter ,如下代码

public class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter
{
    public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        var req = context.Request;
        // Get credential from the Authorization header 
        //(if present) and authenticate
        if (req.Headers.Authorization != null && "basic".Equals(req.Headers.Authorization.Scheme, StringComparison.OrdinalIgnoreCase))
        {
            var rawCreds = req.Headers.Authorization.Parameter;

            var credArray = GetCredentials(rawCreds);

            var clientId = credArray[0];
            var secret = credArray[1];

            if (ValidCredentials(clientId, secret))
            {
                var claims = new List<Claim>()
                      {
                        new Claim(ClaimTypes.Name, clientId)
                      };

                var identity = new ClaimsIdentity(claims, "Basic");
                var principal = new ClaimsPrincipal(new[] { identity });
                // The request message contains valid credential
                context.Principal = principal;
            }
            else
            {
                context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
            }

        }
        else
        {
            context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
        }

        return Task.FromResult(0);
    }

    private string[] GetCredentials(string rawCred)
    {

        var encoding = Encoding.GetEncoding("UTF-8");

        var cred = encoding.GetString(Convert.FromBase64String(rawCred));

        var credArray = cred.Split(':');

        if (credArray.Length == 2)
        {
            return credArray;
        }
        else
        {
            return credArray = ":".Split(':');
        }

    }

    private bool ValidCredentials(string clientId, string secret)
    {

        //compare the values from web.config

        if (clientId == secret)
        {
            return true;
        }
        return false;
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context,CancellationToken cancellationToken)
    {
        context.Result = new ResultWithChallenge(context.Result);
        return Task.FromResult(0);
    }

    public class ResultWithChallenge : IHttpActionResult
    {
        private readonly IHttpActionResult next;
        public ResultWithChallenge(IHttpActionResult next)
        {
            this.next = next;
        }
        public async Task<HttpResponseMessage> ExecuteAsync( CancellationToken cancellationToken)
        {
            var response = await next.ExecuteAsync(cancellationToken);
            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Basic"));
            }
            return response;
        }
    }

    public bool AllowMultiple
    {
        get { return false; }
    }
}

现在,您可以使用它来将您的控制器或动作归为以下代码:

 [OverrideAuthentication]
    [BasicAuthentication]
    [Route("")]
    public async Task<IHttpActionResult> Get()
{
}

请注意,我们是如何创建声明标识并将“身份验证”方案设置为“基本”的,您可以在此处放置任何声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM