1 using System; 2 using System.Collections.Generic; 3 using System.Net.Http.Headers; 4 using System.Security.Principal; 5 using System.Text; 6 using System.Threading; 7 using System.Threading.Tasks; 8 using System.Web.Http.Filters; 9 using System.Web.Http.Results; 10 11 namespace WebApi 12 { 13 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 14 public class AuthenticateAttribute : FilterAttribute, IAuthenticationFilter 15 { 16 private static readonly Dictionary<string, string> UserAccounts; 17 18 static AuthenticateAttribute() 19 { 20 UserAccounts = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) 21 { 22 {"Foo", "Password"}, 23 {"Bar", "Password"}, 24 {"Baz", "Password"} 25 }; 26 } 27 28 public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken) 29 { 30 IPrincipal user = null; 31 var headerValue = context.Request.Headers.Authorization; 32 if (null != headerValue && headerValue.Scheme == "Basic") 33 { 34 var credential = Encoding.Default.GetString(Convert.FromBase64String(headerValue.Parameter)); 35 var split = credential.Split(':'); 36 if (split.Length == 2) 37 { 38 var userName = split[0]; 39 string password; 40 if (UserAccounts.TryGetValue(userName, out password)) 41 { 42 if (password == split[1]) 43 { 44 var identity = new GenericIdentity(userName); 45 user = new GenericPrincipal(identity, new string[0]); 46 } 47 } 48 } 49 } 50 context.Principal = user; 51 return Task.FromResult<object>(null); 52 } 53 54 public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken) 55 { 56 var user = context.ActionContext.ControllerContext.RequestContext.Principal; 57 if (null != user && user.Identity.IsAuthenticated) return Task.FromResult<object>(null); 58 var parameter = $"realm={context.Request.RequestUri.DnsSafeHost}"; 59 var challenge = new AuthenticationHeaderValue("Basic", parameter); 60 context.Result = new UnauthorizedResult(new[] {challenge}, context.Request); 61 return Task.FromResult<object>(null); 62 } 63 } 64 }