web api auth
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; namespace PriceSharePlatform.Common { /// <summary> /// Generic Basic Authentication filter that checks for basic authentication /// headers and challenges for authentication if no authentication is provided /// Sets the Thread Principle with a GenericAuthenticationPrincipal. /// /// You can override the OnAuthorize method for custom auth logic that /// might be application specific. /// </summary> /// <remarks>Always remember that Basic Authentication passes username and passwords /// from client to server in plain text, so make sure SSL is used with basic auth /// to encode the Authorization header on all requests (not just the login). /// </remarks> [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class BasicAuthAttribute : AuthorizationFilterAttribute { bool Active = true; public BasicAuthAttribute() { } /// <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 BasicAuthAttribute(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) {
string tokenX, clientX;
var headers = actionContext.Request.Headers;
if (!headers.Contains("tokenX") || !headers.Contains("clientX"))
{
Challenge1(actionContext);
return;
}
tokenX = headers.GetValues("tokenX").FirstOrDefault();
clientX = headers.GetValues("clientX").FirstOrDefault();
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 also required for some async scenarios //if (HttpContext.Current != null) // HttpContext.Current.User = principal; base.OnAuthorization(actionContext); } }
void Challenge1(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));
}
/// <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) { if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) return false; return true; } /// <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)); // find first : as password allows for : int idx = authHeader.IndexOf(':'); if (idx < 0) return null; string username = authHeader.Substring(0, idx); string password = authHeader.Substring(idx + 1); return new BasicAuthenticationIdentity(username, password); } /// <summary> /// Send the Authentication Challenge request /// </summary> /// <param name="message"></param> /// <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)); } } public class BasicAuthenticationIdentity : GenericIdentity { public BasicAuthenticationIdentity(string name, string password) : base(name, "Basic") { this.Password = password; } /// <summary> /// Basic Auth Password for custom authentication /// </summary> public string Password { get; set; } } }

浙公网安备 33010602011771号