授权来自授权处理程序类的错误

时间:2014-02-14 14:55:17

标签: c# asp.net-web-api basic-authentication

我打电话时似乎无法登录 - api / values。客户端抛出“此请求已拒绝授权”。信息。

我尝试调试basicAuthHandler类,但它似乎没有崩溃任何地方,所以我很少被卡住,我怎么能指出问题。

可能是我的global.aspx中的验证方法或构造函数吗?

public class BasicAuthMessageHandler : DelegatingHandler
  {

    private const string BasicAuthResponseHeader = "WWW-Authenticate";
    private const string BasicAuthResponseHeaderValue = "Basic";

    //[Inject]
    //public iUser Repository { get; set; }

    // private readonly iUser Repository;

    private readonly iUser Repository = new User();

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        AuthenticationHeaderValue authValue = request.Headers.Authorization;
        if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter))
        {
            api_login parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
            if (parsedCredentials != null)
            {
                IPrincipal principal;
                if (TryGetPrincipal(parsedCredentials.username, parsedCredentials.password, out principal))
                {
                    Thread.CurrentPrincipal = principal;
                    //request.GetRequestContext().Principal = principal;
                }
            }
        }

        return base.SendAsync(request, cancellationToken).ContinueWith(task =>
        {
            var response = task.Result;
            if (response.StatusCode == HttpStatusCode.Unauthorized && !response.Headers.Contains(BasicAuthResponseHeader))
            {
                response.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue);
            }

            return response;
        });
    }

    private api_login ParseAuthorizationHeader(string authHeader)
    {
        string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(authHeader)).Split(new[] { ':' });
        if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[1])) return null;

        return new api_login()
        {
            username = credentials[0],
            password = credentials[1],
        };
    }

    private bool TryGetPrincipal(string userName, string password, out IPrincipal principal)
    {
        // this is the method that authenticates against my repository (in this case, hard coded)
        // you can replace this with whatever logic you'd use, but proper separation would put the
        // data access in a repository or separate layer/library.
        api_login user = Repository.Validate2(userName, password);

        if (user.username != null)
        {
            // once the user is verified, assign it to an IPrincipal with the identity name and applicable roles
            principal = new GenericPrincipal(new GenericIdentity(user.username), null);

        }

        principal = null;
        return false;
    }
  }
}

global.aspx:

 GlobalConfiguration.Configuration.MessageHandlers.Add(new BasicAuthMessageHandler());

非常感谢任何帮助。 谢谢。

1 个答案:

答案 0 :(得分:1)

我认为您没有在代码中正确处理响应,我根据您的代码为MessageHandler创建了Basic Authentication,希望它能给您一个好主意(我没有测试它,见下文:

 public class BasicAuthMessageHandler : DelegatingHandler
    {
        private const string BasicAuthResponseHeader = "WWW-Authenticate";
        private const string BasicAuthResponseHeaderValue = "Basic";
        //[Inject]
        //public iUser Repository { get; set; }
        // private readonly iUser Repository;
        private readonly iUser Repository = new User();

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            AuthenticationHeaderValue authValue = request.Headers.Authorization;

            if (authValue == null || authValue.Scheme != BasicAuthResponseHeaderValue)
            {
                return Unauthorized(request);
            }
            string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(authValue.Parameter)).Split(new[] { ':' });
            if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[1]))
            {
                return Unauthorized(request);
            }
            api_login user = Repository.Validate2(credentials[0], credentials[1]);
            if (user == null)
            {
                return Unauthorized(request);
            }
            IPrincipal principal = new GenericPrincipal(new GenericIdentity(user.username, BasicAuthResponseHeaderValue), null);
            Thread.CurrentPrincipal = principal;
            HttpContext.Current.User = principal;

            return base.SendAsync(request, cancellationToken);
        }

        private Task<HttpResponseMessage> Unauthorized(HttpRequestMessage request)
        {
            var response = request.CreateResponse(HttpStatusCode.Unauthorized);
            response.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue); 
            var task = new TaskCompletionSource<HttpResponseMessage>(); 
            task.SetResult(response); 
            return task.Task;
        }

    }