예제 #1
0
        public async Task <AuthenticationResponse> HandleAsync(TokenRequest tokenRequest)
        {
            // Only handle the "client_credentials" grant type
            if (!RequestIsRequiredGrantType())
            {
                return(new AuthenticationResponse {
                    TokenError = new TokenError(TokenErrorType.UnsupportedGrantType)
                });
            }

            // Verify client_id and client_secret are present
            if (!HasIdAndSecret())
            {
                return(new AuthenticationResponse {
                    TokenError = new TokenError(TokenErrorType.InvalidClient)
                });
            }

            // authenticate the client
            var authenticationResult = await _apiClientAuthenticator.TryAuthenticateAsync(
                tokenRequest.Client_id,
                tokenRequest.Client_secret);

            if (!authenticationResult.IsAuthenticated)
            {
                return(new AuthenticationResponse {
                    TokenError = new TokenError(TokenErrorType.InvalidClient)
                });
            }

            // get client information
            var client = await _clientAppRepo.GetClientAsync(authenticationResult.ApiClientIdentity.Key);

            // Convert empty scope to null
            string tokenRequestScope = string.IsNullOrEmpty(tokenRequest.Scope)
                ? null
                : tokenRequest.Scope.Trim();

            // validate client is in scope
            if (tokenRequestScope != null)
            {
                if (!int.TryParse(tokenRequestScope, out int educationOrganizationScope))
                {
                    return(new AuthenticationResponse
                    {
                        TokenError = new TokenError(
                            TokenErrorType.InvalidScope,
                            "The supplied 'scope' was not a number (it should be an EducationOrganizationId that is explicitly associated with the client).")
                    });
                }

                if (!client.ApplicationEducationOrganizations
                    .Select(x => x.EducationOrganizationId)
                    .Contains(educationOrganizationScope))
                {
                    return(new AuthenticationResponse
                    {
                        TokenError = new TokenError(
                            TokenErrorType.InvalidScope,
                            "The client is not explicitly associated with the EducationOrganizationId specified in the requested 'scope'.")
                    });
                }
            }

            // create a new token
            var token = await _accessTokenClientRepo.AddClientAccessTokenAsync(client.ApiClientId, tokenRequestScope);

            var tokenResponse = new TokenResponse();

            tokenResponse.SetToken(token.Id, (int)token.Duration.TotalSeconds, token.Scope);

            return(new AuthenticationResponse {
                TokenResponse = tokenResponse
            });

            bool RequestIsRequiredGrantType() => tokenRequest.Grant_type.EqualsIgnoreCase("client_credentials");

            bool HasIdAndSecret()
            => !string.IsNullOrEmpty(tokenRequest.Client_secret) && !string.IsNullOrEmpty(tokenRequest.Client_id);
        }