Created
March 12, 2020 18:32
-
-
Save derekforeman/9469b9a1a100ac4162bf63c9c2df6da8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Net.Http; | |
using System.Security.Principal; | |
using System.Text; | |
using System.Threading; | |
using System.Web.Http.Controllers; | |
using System.Web.Http.Filters; | |
using BloomAmcatStats.DAL; | |
namespace Stats.Filters | |
{ | |
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] | |
public class BasicAuthenticationFilter : AuthorizationFilterAttribute | |
{ | |
readonly bool _active = true; | |
public BasicAuthenticationFilter() | |
{ } | |
/// <summary> | |
/// Overriden constructor to allow explicit disabling of this | |
/// filter's behavior. Pass false to disable (same as no filter | |
/// but declarative) | |
/// </summary> | |
/// <param name="active"></param> | |
public BasicAuthenticationFilter(bool active) | |
{ | |
_active = active; | |
} | |
/// <summary> | |
/// Override to Web API filter method to handle Basic Auth check | |
/// </summary> | |
/// <param name="actionContext"></param> | |
public override void OnAuthorization(HttpActionContext actionContext) | |
{ | |
if (!_active) return; | |
var identity = ParseAuthorizationHeader(actionContext); | |
if (identity == null) | |
{ | |
Challenge(actionContext); | |
return; | |
} | |
if (!OnAuthorizeUser(identity.Name, identity.Password, actionContext)) | |
{ | |
Challenge(actionContext); | |
return; | |
} | |
var principal = new GenericPrincipal(identity, null); | |
Thread.CurrentPrincipal = principal; | |
// inside of ASP.NET this is required | |
//if (HttpContext.Current != null) | |
// HttpContext.Current.User = principal; | |
base.OnAuthorization(actionContext); | |
} | |
/// <summary> | |
/// Base implementation for user authentication - you probably will | |
/// want to override this method for application specific logic. | |
/// | |
/// The base implementation merely checks for username and password | |
/// present and set the Thread principal. | |
/// | |
/// Override this method if you want to customize Authentication | |
/// and store user data as needed in a Thread Principle or other | |
/// Request specific storage. | |
/// </summary> | |
/// <param name="username"></param> | |
/// <param name="password"></param> | |
/// <param name="actionContext"></param> | |
/// <returns></returns> | |
protected virtual bool OnAuthorizeUser(string username, string password, HttpActionContext actionContext) | |
{ | |
var userRepo = new UserRepository(); | |
var userValidated = userRepo.Authenticate(username, password); | |
return userValidated.LoginResult == 1; | |
} | |
/// <summary> | |
/// Parses the Authorization header and creates user credentials | |
/// </summary> | |
/// <param name="actionContext"></param> | |
protected virtual BasicAuthenticationIdentity ParseAuthorizationHeader(HttpActionContext actionContext) | |
{ | |
string authHeader = null; | |
var auth = actionContext.Request.Headers.Authorization; | |
if (auth != null && auth.Scheme == "Basic") | |
authHeader = auth.Parameter; | |
if (string.IsNullOrEmpty(authHeader)) | |
return null; | |
authHeader = Encoding.Default.GetString(Convert.FromBase64String(authHeader)); | |
char[] splitChar = ":".ToCharArray(); | |
var tokens = authHeader.Split(splitChar, 2); | |
return tokens.Length < 2 ? null : new BasicAuthenticationIdentity(tokens[0], tokens[1]); | |
} | |
/// <summary> | |
/// Send the Authentication Challenge request | |
/// </summary> | |
/// <param name="actionContext"></param> | |
void Challenge(HttpActionContext actionContext) | |
{ | |
var host = actionContext.Request.RequestUri.DnsSafeHost; | |
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); | |
actionContext.Response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", host)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment