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); } }
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)); }