I am new to asp.net core and web API 2 and trying to implement basic authentication in web API like request headers contains the username and password and i will verify them. I have implemented the same thing in Web API using action filters. Now my question is that is it possible to implement basic authentication in web API 2? If possible then can I achieve it with action filters and how? What is the best way to authentication in Web API 2? Should i use middle ware?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
I'm not sure why you said ASP.Net Core and Web API 2. They are mutually exclusive; we don't normally use both in same project.
Now my question is that is it possible to implement basic authentication in web API 2? If possible then can I achieve it with action filters and how? What is the best way to authentication in Web API 2? Should i use middle ware?
In Web API 2, you can easily implement Basic Authentication using DelegatingHandler.
Here is the sample code -
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;
}
}
Credit: Page 121 of ASP.NET Web API 2: Building a REST Service from Start to Finish.