public async Task <DeviceFlowAuthorizationRequest> GetAuthorizationContextAsync(string userCode)
        {
            var deviceAuth = await _devices.FindByUserCodeAsync(userCode);

            if (deviceAuth == null)
            {
                return(null);
            }

            var client = await _clients.FindEnabledClientByIdAsync(deviceAuth.ClientId);

            if (client == null)
            {
                return(null);
            }

            var validatedResources = await _resourceValidator.ValidateRequestedResourcesAsync(new ResourceValidationRequest
            {
                Client = client,
                Scopes = deviceAuth.RequestedScopes,
            });

            return(new DeviceFlowAuthorizationRequest
            {
                Client = client,
                ValidatedResources = validatedResources
            });
        }
        public async Task <DeviceFlowAuthorizationRequest> GetAuthorizationContextAsync(string userCode)
        {
            var deviceAuth = await _devices.FindByUserCodeAsync(userCode);

            if (deviceAuth == null)
            {
                return(null);
            }

            var client = await _clients.FindClientByIdAsync(deviceAuth.ClientId);

            if (client == null)
            {
                return(null);
            }

            var parsedScopesResult = _scopeParser.ParseScopeValues(deviceAuth.RequestedScopes);
            var validatedResources = await _resourceStore.CreateResourceValidationResult(parsedScopesResult);

            return(new DeviceFlowAuthorizationRequest
            {
                Client = client,
                ValidatedResources = validatedResources
            });
        }
        public async Task <DeviceFlowAuthorizationRequest> GetAuthorizationContextAsync(string userCode)
        {
            var deviceAuth = await _devices.FindByUserCodeAsync(userCode);

            if (deviceAuth == null)
            {
                return(null);
            }

            return(new DeviceFlowAuthorizationRequest
            {
                ClientId = deviceAuth.ClientId,
                ScopesRequested = deviceAuth.RequestedScopes
            });
        }
예제 #4
0
        public async Task ProcessAsync_when_generated_expect_user_code_stored()
        {
            var creationTime = DateTime.UtcNow;

            clock.UtcNowFunc = () => creationTime;

            testResult.ValidatedRequest.RequestedScopes = new List <string> {
                "openid", "api1"
            };
            testResult.ValidatedRequest.ValidatedResources = new ResourceValidationResult(new Resources(
                                                                                              identityResources.Where(x => x.Name == "openid"),
                                                                                              apiResources.Where(x => x.Name == "resource"),
                                                                                              scopes.Where(x => x.Name == "api1")));

            var response = await generator.ProcessAsync(testResult, TestBaseUrl);

            response.UserCode.Should().NotBeNullOrWhiteSpace();

            var userCode = await deviceFlowCodeService.FindByUserCodeAsync(response.UserCode);

            userCode.Should().NotBeNull();
            userCode.ClientId.Should().Be(testResult.ValidatedRequest.Client.ClientId);
            userCode.Lifetime.Should().Be(testResult.ValidatedRequest.Client.DeviceCodeLifetime);
            userCode.CreationTime.Should().Be(creationTime);
            userCode.Subject.Should().BeNull();
            userCode.AuthorizedScopes.Should().BeNull();

            userCode.RequestedScopes.Should().Contain(testResult.ValidatedRequest.RequestedScopes);
        }
        /// <summary>
        /// Processes the response.
        /// </summary>
        /// <param name="validationResult">The validation result.</param>
        /// <param name="baseUrl">The base URL.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">validationResult or Client</exception>
        /// <exception cref="ArgumentException">Value cannot be null or whitespace. - baseUrl</exception>
        public virtual async Task <DeviceAuthorizationResponse> ProcessAsync(DeviceAuthorizationRequestValidationResult validationResult, string baseUrl)
        {
            if (validationResult == null)
            {
                throw new ArgumentNullException(nameof(validationResult));
            }
            if (validationResult.ValidatedRequest.Client == null)
            {
                throw new ArgumentNullException(nameof(validationResult.ValidatedRequest.Client));
            }
            if (string.IsNullOrWhiteSpace(baseUrl))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(baseUrl));
            }

            Logger.LogTrace("Creating response for device authorization request");

            var response = new DeviceAuthorizationResponse();

            // generate user_code
            var userCodeGenerator = await UserCodeService.GetGenerator(
                validationResult.ValidatedRequest.Client.UserCodeType ??
                Options.DeviceFlow.DefaultUserCodeType);

            var retryCount = 0;

            while (retryCount < userCodeGenerator.RetryLimit)
            {
                var userCode = await userCodeGenerator.GenerateAsync();

                var deviceCode = await DeviceFlowCodeService.FindByUserCodeAsync(userCode);

                if (deviceCode == null)
                {
                    response.UserCode = userCode;
                    break;
                }

                retryCount++;
            }

            if (response.UserCode == null)
            {
                throw new InvalidOperationException("Unable to create unique device flow user code");
            }

            // generate verification URIs
            response.VerificationUri = Options.UserInteraction.DeviceVerificationUrl;
            if (response.VerificationUri.IsLocalUrl())
            {
                // if url is relative, parse absolute URL
                response.VerificationUri = baseUrl.RemoveTrailingSlash() + Options.UserInteraction.DeviceVerificationUrl;
            }

            if (!string.IsNullOrWhiteSpace(Options.UserInteraction.DeviceVerificationUserCodeParameter))
            {
                response.VerificationUriComplete =
                    $"{response.VerificationUri}?{Options.UserInteraction.DeviceVerificationUserCodeParameter}={response.UserCode}";
            }

            // expiration
            response.DeviceCodeLifetime = validationResult.ValidatedRequest.Client.DeviceCodeLifetime;

            // interval
            response.Interval = Options.DeviceFlow.Interval;

            // store device request (device code & user code)
            response.DeviceCode = await DeviceFlowCodeService.StoreDeviceAuthorizationAsync(response.UserCode, new DeviceCode
            {
                ClientId        = validationResult.ValidatedRequest.Client.ClientId,
                IsOpenId        = validationResult.ValidatedRequest.IsOpenIdRequest,
                Lifetime        = response.DeviceCodeLifetime,
                CreationTime    = Clock.UtcNow.UtcDateTime,
                RequestedScopes = validationResult.ValidatedRequest.ValidatedResources.ScopeValues
            });

            return(response);
        }