Example #1
0
        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);
        }
Example #2
0
        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;
            }));
        }