Exemple #1
0
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            if (!Request.Headers.ContainsKey("Authorization"))
            {
                //Authorization header not in request
                return(AuthenticateResult.NoResult());
            }
            if (!AuthenticationHeaderValue.TryParse(Request.Headers["Authorization"], out AuthenticationHeaderValue headerValue))
            {
                //Invalid Authorization header
                return(AuthenticateResult.NoResult());
            }
            if (!"Basic".Equals(headerValue.Scheme, StringComparison.OrdinalIgnoreCase))
            {
                //Not Basic authentication header
                return(AuthenticateResult.NoResult());
            }
            byte[] headerValueBytes = Convert.FromBase64String(headerValue.Parameter);
            string userAndPassword  = Encoding.UTF8.GetString(headerValueBytes);

            string[] parts = userAndPassword.Split(':');
            if (parts.Length != 2)
            {
                return(AuthenticateResult.Fail("Invalid Basic authentication header"));
            }
            string user     = parts[0];
            string password = parts[1];
            // static password as a secret for backend protection, username is dynamic - the currently authenticated user
            bool isValidUser = password == userContext.SecretKey;

            if (!isValidUser)
            {
                return(AuthenticateResult.Fail("Invalid username or password"));
            }
            var claims = new List <Claim>();

            // we even make access here before we have a user, so we skip the user specific part in case it's just a logon attempt
            if (!String.IsNullOrEmpty(user))
            {
                claims.Add(new Claim(ClaimTypes.Name, user));
                var claimsHeader = Request.Headers["X-User-Claims"];
                if (!string.IsNullOrEmpty(claimsHeader))
                {
                    var userClaims = claimsHeader
                                     .SelectMany(c => c.Split(','))
                                     .Select(c => Encoding.ASCII.GetString(Convert.FromBase64String(c.Trim())))
                                     .Select(c => {
                        var claimParts = c.Split('|');
                        return(new Claim(claimParts[0], claimParts[1]));
                    });
                    claims.AddRange(userClaims);
                }
            }
            var identity = new ClaimsIdentity(claims, Scheme.Name);

            // this keeps the user's identity for business logic purpose
            userContext.SetUserIdentity(identity);
            var principal = new ClaimsPrincipal(identity);
            var ticket    = new AuthenticationTicket(principal, Scheme.Name);

            return(await Task.FromResult(AuthenticateResult.Success(ticket)));
        }