Ejemplo n.º 1
0
        public async Task <IActionResult> AuthenticationRequestAsync(string partyId)
        {
            logger.ScopeTrace(() => "Up, OIDC Authentication request.");
            var oidcUpSequenceData = await sequenceLogic.GetSequenceDataAsync <OidcUpSequenceData>(remove : false);

            if (!oidcUpSequenceData.UpPartyId.Equals(partyId, StringComparison.Ordinal))
            {
                throw new Exception("Invalid up-party id.");
            }
            logger.SetScopeProperty(Constants.Logs.UpPartyId, oidcUpSequenceData.UpPartyId);

            var party = await tenantRepository.GetAsync <TParty>(oidcUpSequenceData.UpPartyId);

            logger.SetScopeProperty(Constants.Logs.UpPartyClientId, party.Client.ClientId);

            await oidcDiscoveryReadUpLogic.CheckOidcDiscoveryAndUpdatePartyAsync(party);

            var nonce            = RandomGenerator.GenerateNonce();
            var loginCallBackUrl = HttpContext.GetUpPartyUrl(party.Name, Constants.Routes.OAuthController, Constants.Endpoints.AuthorizationResponse, partyBindingPattern: party.PartyBindingPattern);

            oidcUpSequenceData.ClientId    = !party.Client.SpClientId.IsNullOrWhiteSpace() ? party.Client.SpClientId : party.Client.ClientId;
            oidcUpSequenceData.RedirectUri = loginCallBackUrl;
            oidcUpSequenceData.Nonce       = nonce;
            if (party.Client.EnablePkce)
            {
                var codeVerifier = RandomGenerator.Generate(64);
                oidcUpSequenceData.CodeVerifier = codeVerifier;
            }
            await sequenceLogic.SaveSequenceDataAsync(oidcUpSequenceData);

            var authenticationRequest = new AuthenticationRequest
            {
                ClientId     = oidcUpSequenceData.ClientId,
                ResponseMode = party.Client.ResponseMode,
                ResponseType = party.Client.ResponseType,
                RedirectUri  = loginCallBackUrl,
                Nonce        = nonce,
                State        = await sequenceLogic.CreateExternalSequenceIdAsync()
            };

            switch (oidcUpSequenceData.LoginAction)
            {
            case LoginAction.ReadSession:
                authenticationRequest.Prompt = IdentityConstants.AuthorizationServerPrompt.None;
                break;

            case LoginAction.RequireLogin:
                authenticationRequest.Prompt = IdentityConstants.AuthorizationServerPrompt.Login;
                break;

            default:
                break;
            }

            if (oidcUpSequenceData.MaxAge.HasValue)
            {
                authenticationRequest.MaxAge = oidcUpSequenceData.MaxAge;
            }

            if (!oidcUpSequenceData.UserId.IsNullOrEmpty())
            {
                authenticationRequest.LoginHint = oidcUpSequenceData.UserId;
            }

            authenticationRequest.Scope = new[] { IdentityConstants.DefaultOidcScopes.OpenId }.ConcatOnce(party.Client.Scopes).ToSpaceList();

            //TODO add AcrValues
            //authenticationRequest.AcrValues = "urn:federation:authentication:windows";

            logger.ScopeTrace(() => $"Up, Authentication request '{authenticationRequest.ToJsonIndented()}'.", traceType: TraceTypes.Message);
            var nameValueCollection = authenticationRequest.ToDictionary();

            if (party.Client.EnablePkce)
            {
                var codeChallengeRequest = new CodeChallengeSecret
                {
                    CodeChallenge       = await oidcUpSequenceData.CodeVerifier.Sha256HashBase64urlEncodedAsync(),
                    CodeChallengeMethod = IdentityConstants.CodeChallengeMethods.S256,
                };

                logger.ScopeTrace(() => $"Up, CodeChallengeSecret request '{codeChallengeRequest.ToJsonIndented()}'.", traceType: TraceTypes.Message);
                nameValueCollection = nameValueCollection.AddToDictionary(codeChallengeRequest);
            }

            securityHeaderLogic.AddFormActionAllowAll();

            logger.ScopeTrace(() => $"Up, Authentication request URL '{party.Client.AuthorizeUrl}'.");
            logger.ScopeTrace(() => "Up, Sending OIDC Authentication request.", triggerEvent: true);
            return(await nameValueCollection.ToRedirectResultAsync(party.Client.AuthorizeUrl));
        }