public void DataOfVariousLengthRoundTripCorrectly() { for (int length = 0; length != 256; ++length) { var data = new byte[length]; for (int index = 0; index != length; ++index) { data[index] = (byte)(5 + length + (index * 23)); } string text = Base64UrlTextEncoder.Encode(data); byte[] result = Base64UrlTextEncoder.Decode(text); for (int index = 0; index != length; ++index) { Assert.Equal(data[index], result[index]); } } }
protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync() { var query = Request.Query; byte[] challengeBytes; using var sha256mac = new HMACSHA256(Encoding.UTF8.GetBytes(Options.AuthenticationSecret)); challengeBytes = sha256mac.ComputeHash(Encoding.UTF8.GetBytes(query["sso"])); byte[] signatureBytes = HexStringToByteArray(query["sig"]); if (signatureBytes.Length != challengeBytes.Length) { return(HandleRequestResult.Fail("Signature mismatch")); } for (int ix = 0; ix < signatureBytes.Length; ++ix) { if (signatureBytes[ix] != challengeBytes[ix]) { return(HandleRequestResult.Fail("Signature mismatch")); } } var properties = Options.StateDataFormat.Unprotect(Request.Cookies["StateCookie"]); if (properties == null) { Logger.LogError("Authentication Properties not found"); properties = new AuthenticationProperties(); } else if (!ValidateCorrelationId(properties)) { //return HandleRequestResult.Fail("Discourse correlation failed.", properties); Logger.LogError("Discourse correlation failed."); } string encodedData = Encoding.UTF8.GetString(Base64UrlTextEncoder.Decode(query["sso"])); var userInfo = HttpUtility.ParseQueryString(encodedData); var identity = new ClaimsIdentity(ClaimsIssuer); foreach (var key in userInfo.AllKeys) { switch (key) { case "groups": { var groups = userInfo[key].Split(","); foreach (var group in groups) { identity.AddClaim(new Claim(ClaimTypes.Role, group)); } break; } case "name": { identity.AddClaim(new Claim(ClaimTypes.Name, Uri.UnescapeDataString(userInfo[key]).Replace('+', ' '))); break; } case "email": { identity.AddClaim(new Claim(ClaimTypes.Email, userInfo[key].ToLowerInvariant())); break; } case "external_id": { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userInfo[key])); break; } case "username": { identity.AddClaim(new Claim(ClaimTypes.UserData, userInfo[key])); break; } case "return_sso_url": case "nonce": break; default: identity.AddClaim(new Claim(key, userInfo[key])); break; } } if (string.IsNullOrEmpty(query["returnUrl"]) == false) { properties.RedirectUri = query["returnUrl"]; } var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Scheme.Name); return(HandleRequestResult.Success(ticket)); }