Ejemplo n.º 1
0
        public TeamsFxValueProvider(TeamsFxContext config, ILogger logger)
        {
            _logger = logger;

            try
            {
                configStr = JsonConvert.SerializeObject(config);
            }
            catch (Exception ex)
            {
                var message = "Fail to serialize config object." + ex.Message;
                _logger.LogError(message);
                throw new Exception(message);
            }
        }
Ejemplo n.º 2
0
        public async Task <IValueProvider> BindAsync(BindingContext context)
        {
            _logger.LogDebug($"TeamsFx version:{GlobalConfig.TeamsFxVersion}.");

            // Get configuration settings
            var accessToken = string.Empty;

            // Get the access token in HTTP request header and do authorization for http trigger
            // We rely on Web App authentication feature to validate the token, assume the authorization token is valid
            if (context.BindingData.ContainsKey(RequestBindingName))
            {
                _logger.LogDebug("Do authorization for access token in HTTP request ");

                var httpRequest = context.BindingData[RequestBindingName] as HttpRequest;
                accessToken = httpRequest.Headers[HeaderNames.Authorization];
                // Do extra check to avoid errors in local debugging scenario
                if (string.IsNullOrEmpty(accessToken))
                {
                    var responseBody = "No authorization header in http request.";
                    await ModifyHttpResponse(httpRequest.HttpContext.Response, 401, responseBody).ConfigureAwait(false);

                    _logger.LogDebug(responseBody);
                    throw new Exception(responseBody);
                }
                var claim = new JwtBuilder().Decode <Dictionary <string, object> >(accessToken);

                // Only allow access token whose client id is in the list of `ALLOWED_APP_IDS` or equals to `CLIENT_ID` setting.
                try
                {
                    ValidateClientId(claim);
                }
                catch (AuthorizationException e)
                {
                    await ModifyHttpResponse(httpRequest.HttpContext.Response, 403, e.Message).ConfigureAwait(false);

                    _logger.LogDebug("Authorization exception while validating client id. Error message: " + e.Message);
                    throw;
                }
                catch (Exception e)
                {
                    var message = "Unexpected exception thrown when validating client id: " + e.Message;
                    _logger.LogDebug(message);
                    throw new Exception(message);
                }

                // Refresh user access token if it's about to expire
                // Follow official recommendation: https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens#user-and-application-tokens
                if (!claim.ContainsKey(JwtClaim.Idtyp) || ((string)claim[JwtClaim.Idtyp]) != Constants.IdtypApp) // Prerequisite: the AAD app configured for Function App requires idtyp optional claim
                {
                    _logger.LogDebug("User access token. Check if needs refreshing.");
                    var exp = (long)claim[JwtClaim.Exp];
                    _logger.LogDebug("exp: " + exp);
                    if (exp < UnixEpoch.GetSecondsSince(DateTimeOffset.UtcNow.AddMinutes(_bindingAttribute.TokenRefreshBufferMinutes))) // Refresh if token will expire in given time
                    {
                        accessToken = await GetRefreshedToken(accessToken, claim).ConfigureAwait(false);
                    }
                }
            }
            else
            {
                _logger.LogDebug("Fail to find " + RequestBindingName + " in context binding data.");
            }

            // Return a value provider
            var config = new TeamsFxContext
            {
                AccessToken = accessToken.Substring("Bearer ".Length)
            };

            return(new TeamsFxValueProvider(config, _logger));
        }