public void VerifyRequestWithBody() { // Arrange var samlToken = Resources.HoKSamlToken; var authCalculator = AuthCalculatorFactory.Create(); var request = RequestFactory.Create(HttpMethod.POST, "/api/session", "127.0.0.1", 80, "{'body': 'test'}"); var generatedToken = authCalculator.ComputeToken(request, _signingCertificate, SigningAlgorithm.RSA_SHA256, samlToken); var authVerifier = AuthVerifierFactory.Create(10, 10); // Act var actualSamlToken = authVerifier.VerifyToken(request, generatedToken); // Assert Assert.AreEqual(samlToken, actualSamlToken.RawXml); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { // Allow Synchornous IO for this request to be able to read Request Body Stream // which is part of the SIGN authentication validation var syncIOFeature = Context.Features.Get <IHttpBodyControlFeature>(); if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; } return(await Task.Run( () => { AuthenticateResult result = null; try { _logger.Log(LogLevel.Debug, "Handle SIGN Authentication Start"); // Authorization Header should conform https://wiki.eng.vmware.com/SSO/REST var authZValue = Request.Headers["Authorization"].FirstOrDefault(); // Service support multiple Authentication header, check // this handler should handle current one if (!string.IsNullOrEmpty(authZValue) && authZValue.StartsWith(Constants.SignAuthenticationScheme)) { List <string> signAuthzTokens = new List <string>(); // Get SIGN Authnetication token. // Depending on the length of the SAML token SIGN 'Authorization' could be presented with multiple header values foreach (var token in authZValue.Split(',', ';')) { if (!string.IsNullOrEmpty(token.Trim())) { signAuthzTokens.Add(token.Trim()); } } // If forwarded from a reverse proxy, read the X-Forwarded headers var forwardedHost = Request.Headers["X-Forwarded-Host"].FirstOrDefault(); var forwardedProto = Request.Headers["X-Forwarded-Proto"].FirstOrDefault(); _logger.Log(LogLevel.Debug, $"SIGN authorization Request X-Forwarded-Host: {forwardedHost}"); _logger.Log(LogLevel.Debug, $"SIGN authorization Request X-Forwarded-Proto: {forwardedProto}"); var request = new SignAuthenticationRequest(Request, forwardedHost, forwardedProto); _logger.Log(LogLevel.Debug, $"SIGN authorization request Method: {request.Method}"); _logger.Log(LogLevel.Debug, $"SIGN authorization request Uri: {request.RequestUri}"); _logger.Log(LogLevel.Debug, $"SIGN authorization request Port: {request.Port}"); _logger.Log(LogLevel.Debug, $"SIGN authorization request HostName: {request.HostName}"); // Verify Authorization header and get valid SAML token as a result _logger.Log(LogLevel.Debug, $"Verify SIGN authorization token"); var authVerifier = AuthVerifierFactory.Create(60, 60); var samlToken = authVerifier.VerifyToken(request, signAuthzTokens.ToArray()); // Issue session for the subject of the SAML token _logger.Log(LogLevel.Debug, $"Issue Session Token for valid SIGN authorization token"); var sessionsToken = SessionToken.Issue(samlToken); Response.Headers.Add(APIGatewayResources.SRSAuthorizationHeader, sessionsToken.SessionId); // Issue Solution ActAs HoK SAML Token by for the Subject that authenticates" _logger.Log(LogLevel.Debug, $"Issue SRS Solution ActAs HoK token for the subject"); var srsSessionHoKToken = new SolutionStsClient(_loggerFactory, Options) .IssueSolutionTokenByToken( samlToken.RawXmlElement); sessionsToken.HoKSamlToken = new SamlToken(srsSessionHoKToken.OuterXml); var claims = new[] { new Claim(ClaimTypes.Name, sessionsToken.UserName), }; var identity = new ClaimsIdentity(claims, Constants.SignAuthenticationScheme); var principal = new ClaimsPrincipal(identity); ; result = AuthenticateResult.Success( new AuthenticationTicket(principal, Constants.SignAuthenticationScheme)); } } catch (Exception exc) { _logger.Log(LogLevel.Error, $"SIGN Authorization failure: {exc}"); result = AuthenticateResult.Fail(exc.Message); } return result; })); }