如何从控制器访问用户名

时间:2017-01-20 18:51:09

标签: asp.net asp.net-mvc asp.net-web-api asp.net-web-api2

我正在编写我的第一个Web API 2.我正在使用自定义HttpMessageHandler执行授权。但是,我的控制器需要知道凭证中指定的用户名。

研究此问题时,ApiController似乎没有Controller.HttpContext property。我发现访问HttpContext.Current存在潜在问题。因此,虽然我实际上能够将HttpContext.Current.Items中的用户名存储在我的HttpMessageHandler中,然后从我的控制器访问该信息,但我不确定它是否始终可靠。

我也看到了使用RequestContext.Principal property的建议;但是,我无法在此数据中的任何位置找到当前请求的用户名。

我的控制器如何可靠地获取当前请求的用户名?

注意:我指的是用户名,但在这种情况下,实际用户是另一个调用API的软件。 "用户名"反映正在进行通话的软件。

1 个答案:

答案 0 :(得分:2)

  

@Win:嗯,那部分是我正在开发的。但目前基本   认证似乎合适,用户名识别   联系我们的软件和密码是一个特殊的密钥

以下是 BasicAuthenticationMessageHandler 的示例代码,它使用消息处理程序来支持HTTP基本身份验证。

您可以在ASP.NET Web API 2: Building a REST Service from Start to Finish的第121页阅读更多内容。

IBasicSecurityService

public interface IBasicSecurityService
{
    bool SetPrincipal(string username, string password);
}

BasicSecurityService

public class BasicSecurityService : IBasicSecurityService
{
    public bool SetPrincipal(string username, string password)
    {
        // Get user from database
        var user = GetUser(username);
        IPrincipal principal = null;
        if (user == null || (principal = GetPrincipal(user)) == null)
        {
            // System could not validate user
            return false;
        }

        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
        {
            HttpContext.Current.User = principal;
        }

        return true;
    }

    public virtual IPrincipal GetPrincipal(User user)
    {
        var identity = new GenericIdentity(user.Username, Constants.SchemeTypes.Basic);

        identity.AddClaim(new Claim(ClaimTypes.GivenName, user.Firstname));
        identity.AddClaim(new Claim(ClaimTypes.Surname, user.Lastname));
        // Get authroized roles and add them as Role Claim.
        identity.AddClaim(new Claim(ClaimTypes.Role, "Manager"));

        return new ClaimsPrincipal(identity);
    }
}

BasicAuthenticationMessageHandler

public class BasicAuthenticationMessageHandler : DelegatingHandler
{
    public const char AuthorizationHeaderSeparator = ':';
    private const int UsernameIndex = 0;
    private const int PasswordIndex = 1;
    private const int ExpectedCredentialCount = 2;

    private readonly IBasicSecurityService _basicSecurityService;

    public BasicAuthenticationMessageHandler(IBasicSecurityService basicSecurityService)
    {
        _basicSecurityService = basicSecurityService;
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        if (HttpContext.Current.User.Identity.IsAuthenticated)
        {
            // Already authenticated; passing on to next handler...
            return await base.SendAsync(request, cancellationToken);
        }

        if (!CanHandleAuthentication(request))
        {
            // Not a basic auth request; passing on to next handler...
            return await base.SendAsync(request, cancellationToken);
        }

        bool isAuthenticated;
        try
        {
            isAuthenticated = Authenticate(request);
        }
        catch (Exception e)
        {
            // Failure in auth processing
            return CreateUnauthorizedResponse();
        }

        if (isAuthenticated)
        {
            var response = await base.SendAsync(request, cancellationToken);
            return response;
        }

        return CreateUnauthorizedResponse();
    }

    public bool CanHandleAuthentication(HttpRequestMessage request)
    {
        return (request.Headers != null
                && request.Headers.Authorization != null
                && request.Headers.Authorization.Scheme.ToLowerInvariant() == Constants.SchemeTypes.Basic);
    }

    public bool Authenticate(HttpRequestMessage request)
    {
        // Attempting to authenticate...
        var authHeader = request.Headers.Authorization;
        if (authHeader == null)
        {
            return false;
        }

        var credentialParts = GetCredentialParts(authHeader);
        if (credentialParts.Length != ExpectedCredentialCount)
        {
            return false;
        }

        return _basicSecurityService.SetPrincipal(credentialParts[UsernameIndex], credentialParts[PasswordIndex]);
    }

    public string[] GetCredentialParts(AuthenticationHeaderValue authHeader)
    {
        var encodedCredentials = authHeader.Parameter;
        var credentialBytes = Convert.FromBase64String(encodedCredentials);
        var credentials = Encoding.ASCII.GetString(credentialBytes);
        var credentialParts = credentials.Split(AuthorizationHeaderSeparator);
        return credentialParts;
    }

    public HttpResponseMessage CreateUnauthorizedResponse()
    {
        var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue(Constants.SchemeTypes.Basic));
        return response;
    }
}