/// <summary>
        /// Action for exchanging a JWT generated by <c>Maskinporten</c> with a new JWT for further use as authentication against rest of Altinn.
        /// </summary>
        /// <returns>The result of the action. Contains the new token if the old token was valid and could be exchanged.</returns>
        private async Task <ActionResult> AuthenticateMaskinportenToken(string originalToken, bool test)
        {
            try
            {
                ICollection <SecurityKey> signingKeys =
                    await _signingKeysRetriever.GetSigningKeys(_generalSettings.GetMaskinportenWellKnownConfigEndpoint);

                TokenValidationParameters validationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKeys        = signingKeys,
                    ValidateIssuer           = false,
                    ValidateAudience         = false,
                    RequireExpirationTime    = true,
                    ValidateLifetime         = true,
                    ClockSkew = TimeSpan.Zero
                };

                ClaimsPrincipal originalPrincipal = _validator.ValidateToken(originalToken, validationParameters, out _);
                _logger.LogInformation("Token is valid");

                string issOriginal = originalPrincipal.Claims.Where(c => c.Type.Equals(IssClaimName)).Select(c => c.Value).FirstOrDefault();
                if (issOriginal == null || !_generalSettings.GetMaskinportenWellKnownConfigEndpoint.Contains(issOriginal))
                {
                    _logger.LogInformation("Invalid issuer " + issOriginal);
                    return(Unauthorized());
                }

                string orgNumber = GetOrganisationNumberFromConsumerClaim(originalPrincipal);

                if (string.IsNullOrEmpty(orgNumber))
                {
                    _logger.LogInformation("Invalid consumer claim");
                    return(Unauthorized());
                }

                List <Claim> claims = new List <Claim>();
                foreach (Claim claim in originalPrincipal.Claims)
                {
                    claims.Add(claim);
                }

                string issuer = _generalSettings.PlatformEndpoint;

                string org = null;

                if (HasServiceOwnerScope(originalPrincipal))
                {
                    org = await _organisationService.LookupOrg(orgNumber);

                    if (org == "digdir" && test)
                    {
                        org = "ttd";
                    }

                    if (!string.IsNullOrEmpty(org))
                    {
                        claims.Add(new Claim(AltinnCoreClaimTypes.Org, org, ClaimValueTypes.String, issuer));
                    }
                }

                string authenticatemethod = "maskinporten";

                if (!string.IsNullOrEmpty(Request.Headers["X-Altinn-EnterpriseUser-Authentication"]))
                {
                    string enterpriseUserHeader = Request.Headers["X-Altinn-EnterpriseUser-Authentication"];

                    (UserAuthenticationResult authenticatedEnterpriseUser, ActionResult error) = await HandleEnterpriseUserLogin(enterpriseUserHeader, orgNumber);

                    if (error != null)
                    {
                        return(error);
                    }

                    if (authenticatedEnterpriseUser != null)
                    {
                        authenticatemethod = "virksomhetsbruker";

                        string userID   = authenticatedEnterpriseUser.UserID.ToString();
                        string username = authenticatedEnterpriseUser.Username;
                        string partyId  = authenticatedEnterpriseUser.PartyID.ToString();

                        claims.Add(new Claim(AltinnCoreClaimTypes.UserId, userID, ClaimValueTypes.Integer32, issuer));
                        claims.Add(new Claim(AltinnCoreClaimTypes.UserName, username, ClaimValueTypes.String, issuer));
                        claims.Add(new Claim(AltinnCoreClaimTypes.PartyID, partyId, ClaimValueTypes.Integer32, issuer));
                    }
                }

                claims.Add(new Claim(AltinnCoreClaimTypes.OrgNumber, orgNumber, ClaimValueTypes.Integer32, issuer));
                claims.Add(new Claim(AltinnCoreClaimTypes.AuthenticateMethod, authenticatemethod, ClaimValueTypes.String, issuer));
                claims.Add(new Claim(AltinnCoreClaimTypes.AuthenticationLevel, "3", ClaimValueTypes.Integer32, issuer));

                string[] claimTypesToRemove = { "aud", "iss", "client_amr" };
                foreach (string claimType in claimTypesToRemove)
                {
                    Claim audClaim = claims.Find(c => c.Type == claimType);
                    claims.Remove(audClaim);
                }

                claims.Add(new Claim("iss", issuer, ClaimValueTypes.String, issuer));

                ClaimsIdentity identity = new ClaimsIdentity(OrganisationIdentity);

                identity.AddClaims(claims);
                ClaimsPrincipal principal = new ClaimsPrincipal(identity);

                string serializedToken = await GenerateToken(principal);

                return(Ok(serializedToken));
            }
            catch (Exception ex)
            {
                _logger.LogWarning($"Organisation authentication failed. {ex.Message}");
                return(Unauthorized());
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Action for exchanging a JWT generated by <c>Maskinporten</c> with a new JWT for further use as authentication against rest of Altinn.
        /// </summary>
        /// <returns>The result of the action. Contains the new token if the old token was valid and could be exchanged.</returns>
        private async Task <ActionResult> AuthenticateMaskinportenToken(string originalToken, bool test)
        {
            try
            {
                ICollection <SecurityKey> signingKeys =
                    await _signingKeysRetriever.GetSigningKeys(_generalSettings.GetMaskinportenWellKnownConfigEndpoint);

                TokenValidationParameters validationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKeys        = signingKeys,
                    ValidateIssuer           = false,
                    ValidateAudience         = false,
                    RequireExpirationTime    = true,
                    ValidateLifetime         = true,
                    ClockSkew = TimeSpan.Zero
                };

                ClaimsPrincipal originalPrincipal = _validator.ValidateToken(originalToken, validationParameters, out _);
                _logger.LogInformation("Token is valid");

                string orgNumber = GetOrganisationNumberFromConsumerClaim(originalPrincipal);

                if (string.IsNullOrEmpty(orgNumber))
                {
                    _logger.LogInformation("Invalid consumer claim");
                    return(Unauthorized());
                }

                List <Claim> claims = new List <Claim>();
                foreach (Claim claim in originalPrincipal.Claims)
                {
                    claims.Add(claim);
                }

                string issuer = _generalSettings.PlatformEndpoint;

                string org = null;

                if (HasServiceOwnerScope(originalPrincipal))
                {
                    org = await _organisationService.LookupOrg(orgNumber);

                    if (org == "digdir" && test)
                    {
                        org = "ttd";
                    }

                    if (!string.IsNullOrEmpty(org))
                    {
                        claims.Add(new Claim(AltinnCoreClaimTypes.Org, org, ClaimValueTypes.String, issuer));
                    }
                }

                claims.Add(new Claim(AltinnCoreClaimTypes.OrgNumber, orgNumber, ClaimValueTypes.Integer32, issuer));
                claims.Add(new Claim(AltinnCoreClaimTypes.AuthenticateMethod, "maskinporten", ClaimValueTypes.String, issuer));
                claims.Add(new Claim(AltinnCoreClaimTypes.AuthenticationLevel, "3", ClaimValueTypes.Integer32, issuer));

                string[] claimTypesToRemove = { "aud", "iss", "client_amr" };
                foreach (string claimType in claimTypesToRemove)
                {
                    Claim audClaim = claims.Find(c => c.Type == claimType);
                    claims.Remove(audClaim);
                }

                claims.Add(new Claim("iss", issuer, ClaimValueTypes.String, issuer));

                ClaimsIdentity identity = new ClaimsIdentity(OrganisationIdentity);

                identity.AddClaims(claims);
                ClaimsPrincipal principal = new ClaimsPrincipal(identity);

                string serializedToken = await GenerateToken(principal);

                return(Ok(serializedToken));
            }
            catch (Exception ex)
            {
                _logger.LogWarning($"Organisation authentication failed. {ex.Message}");
                return(Unauthorized());
            }
        }