protected async Task <SubscriptionEntry[]> GetSubscriptionsFromAttributeAsync(GraphWebhookSubscriptionAttribute attribute, CancellationToken cancellationToken)
            {
                IEnumerable <SubscriptionEntry> subscriptionEntries = await _subscriptionStore.GetAllSubscriptionsAsync();

                if (TokenIdentityMode.UserFromRequest.ToString().Equals(attribute.Filter, StringComparison.OrdinalIgnoreCase))
                {
                    var dummyTokenAttribute = new TokenAttribute()
                    {
                        Resource         = _options.GraphBaseUrl,
                        Identity         = TokenIdentityMode.UserFromToken,
                        UserToken        = attribute.UserToken,
                        IdentityProvider = "AAD",
                    };
                    var graph = await _clientManager.GetMSGraphClientFromTokenAttributeAsync(dummyTokenAttribute, cancellationToken);

                    var user = await graph.Me.Request().GetAsync();

                    subscriptionEntries = subscriptionEntries.Where(entry => entry.UserId.Equals(user.Id));
                }
                else if (attribute.Filter != null)
                {
                    throw new InvalidOperationException($"There is no filter for {attribute.Filter}");
                }
                return(subscriptionEntries.ToArray());
            }
        private JwtSecurityToken CreateTokenForEasyAuthAccess(TokenAttribute attribute)
        {
            if (string.IsNullOrEmpty(attribute.UserId))
            {
                throw new ArgumentException("A userId is required to obtain an access token.");
            }

            if (string.IsNullOrEmpty(attribute.IdentityProvider))
            {
                throw new ArgumentException("A provider is necessary to obtain an access token.");
            }

            var identityClaims = new ClaimsIdentity(attribute.UserId);

            identityClaims.AddClaim(new System.Security.Claims.Claim(ClaimTypes.NameIdentifier, attribute.UserId));
            identityClaims.AddClaim(new System.Security.Claims.Claim("idp", attribute.IdentityProvider));

            var baseUrl = _client.GetBaseUrl();
            var descr   = new SecurityTokenDescriptor
            {
                Audience           = baseUrl,
                Issuer             = baseUrl,
                Subject            = identityClaims,
                Expires            = DateTime.UtcNow.AddMinutes(_jwtTokenDurationInMinutes),
                SigningCredentials = new HmacSigningCredentials(_signingKey),
            };

            return((JwtSecurityToken)JwtHandler.CreateToken(descr));
        }
Ejemplo n.º 3
0
 public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering)
 {
     if (isAltering == false)
     {
         attribute.Token.ItemSeparator = attribute.Value;
     }
 }
Ejemplo n.º 4
0
        public async Task RefreshToken(JwtSecurityToken jwt, TokenAttribute attribute)
        {
            if (string.IsNullOrEmpty(attribute.Resource))
            {
                throw new ArgumentException("A resource is required to renew an access token.");
            }

            if (string.IsNullOrEmpty(attribute.UserId))
            {
                throw new ArgumentException("A userId is required to renew an access token.");
            }

            if (string.IsNullOrEmpty(attribute.IdentityProvider))
            {
                throw new ArgumentException("A provider is necessary to renew an access token.");
            }

            string refreshUrl = _baseUrl + $".auth/refresh?resource=" + WebUtility.UrlEncode(attribute.Resource);

            using (var refreshRequest = new HttpRequestMessage(HttpMethod.Get, refreshUrl))
            {
                refreshRequest.Headers.Add("x-zumo-auth", jwt.RawData);
                _log.Verbose($"Refreshing ${attribute.IdentityProvider} access token for user ${attribute.UserId} at ${refreshUrl}");
                using (HttpResponseMessage response = await _httpClient.SendAsync(refreshRequest))
                {
                    _log.Verbose($"Response from ${refreshUrl}: {response.StatusCode}");
                    if (!response.IsSuccessStatusCode)
                    {
                        string errorResponse = await response.Content.ReadAsStringAsync();

                        throw new InvalidOperationException($"Failed to refresh {attribute.UserId} {attribute.IdentityProvider} error={response.StatusCode} {errorResponse}");
                    }
                }
            }
        }
        /// <summary>
        /// Hydrate GraphServiceClient from a moniker (serialized TokenAttribute)
        /// </summary>
        /// <param name="moniker">string representing serialized TokenAttribute</param>
        /// <returns>Authenticated GraphServiceClient</returns>
        public async Task <IGraphServiceClient> GetMSGraphClientFromUserIdAsync(string userId, CancellationToken token)
        {
            var attr = new TokenAttribute
            {
                UserId   = userId,
                Resource = _options.GraphBaseUrl,
                Identity = TokenIdentityMode.UserFromId,
            };

            return(await this.GetMSGraphClientFromTokenAttributeAsync(attr, token));
        }
Ejemplo n.º 6
0
 public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering)
 {
     if (isAltering)
     {
         var maxQuantity = Convert.ToInt32(attribute.Value);
         while (currentValues.Count > maxQuantity)
         {
             currentValues.RemoveAt(maxQuantity);
         }
     }
 }
        /// <summary>
        /// Hydrate GraphServiceClient from a moniker (serialized TokenAttribute)
        /// </summary>
        /// <param name="moniker">string representing serialized TokenAttribute</param>
        /// <returns>Authenticated GraphServiceClient</returns>
        internal async Task <IGraphServiceClient> GetMSGraphClientFromUserIdAsync(string userId)
        {
            var attr = new TokenAttribute
            {
                UserId   = userId,
                Resource = O365Constants.GraphBaseUrl,
                Identity = TokenIdentityMode.UserFromId,
            };

            return(await this.GetMSGraphClientAsync(attr));
        }
Ejemplo n.º 8
0
        public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering)
        {
            if (isAltering)
            {
                for (var i = 0; i < currentValues.Count; i++)
                {
                    double number;
                    var    isNumber = double.TryParse(currentValues[i], out number);

                    currentValues[i] = currentValues[i].Prefix((isNumber ? '0' : ' '), Convert.ToInt32(attribute.Value));
                }
            }
        }
        /// <summary>
        /// Either retrieve existing GSC or create a new one
        /// GSCs are cached using a combination of the user's principal ID and the scopes of the token used to authenticate
        /// </summary>
        /// <param name="attribute">Token attribute with either principal ID or ID token</param>
        /// <returns>Authenticated GSC</returns>
        public virtual async Task <IGraphServiceClient> GetMSGraphClientAsync(TokenAttribute attribute)
        {
            string token = await this._tokenExtension.GetAccessTokenAsync(attribute);

            string principalId = GetTokenOID(token);

            var key = string.Concat(principalId, " ", GetTokenOrderedScopes(token));

            CachedClient client = null;

            // Check to see if there already exists a GSC associated with this principal ID and the token scopes.
            if (this._clients.TryGetValue(key, out client))
            {
                // Check if token is expired
                if (client.expirationDate < DateTimeOffset.Now.ToUnixTimeSeconds())
                {
                    // Need to update the client's token & expiration date
                    // $$ todo -- just reset token instead of whole new authentication provider?
                    client.client.AuthenticationProvider = new DelegateAuthenticationProvider(
                        (requestMessage) =>
                    {
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);

                        return(Task.CompletedTask);
                    });
                    client.expirationDate = GetTokenExpirationDate(token);
                }

                return(client.client);
            }
            else
            {
                client = new CachedClient
                {
                    client = new GraphServiceClient(
                        new DelegateAuthenticationProvider(
                            (requestMessage) =>
                    {
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
                        return(Task.CompletedTask);
                    })),
                    expirationDate = GetTokenExpirationDate(token),
                };
                this._clients.TryAdd(key, client);
                return(client.client);
            }
        }
Ejemplo n.º 10
0
        public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering)
        {
            if (isAltering)
            {
                if (currentValues.Count == 0)
                {
                    // If it has no current values, then we add the dafault value.
                    currentValues.Add(attribute.Value);
                    return;
                }

                for (var i = 0; i < currentValues.Count; i++)
                {
                    currentValues[i] = String.IsNullOrEmpty(currentValues[i]) ? attribute.Value : currentValues[i];
                }
            }
        }
        /// <summary>
        /// Retrieve Easy Auth token based on provider & principal ID
        /// </summary>
        /// <param name="attribute">The metadata for the token to grab</param>
        /// <returns>Task with Token Store entry of the token</returns>
        public async Task <string> GetEasyAuthAccessTokenAsync(TokenAttribute attribute)
        {
            var jwt = CreateTokenForEasyAuthAccess(attribute);
            EasyAuthTokenStoreEntry tokenStoreEntry = await _client.GetTokenStoreEntry(jwt, attribute);

            bool isTokenValid   = IsTokenValid(tokenStoreEntry.AccessToken);
            bool isTokenExpired = tokenStoreEntry.ExpiresOn <= DateTime.UtcNow.AddMinutes(GraphTokenBufferInMinutes);
            bool isRefreshable  = IsRefreshableProvider(attribute.IdentityProvider);

            if (isRefreshable && (isTokenExpired || !isTokenValid))
            {
                await _client.RefreshToken(jwt, attribute);

                // Now that the refresh has occured, grab the new token
                tokenStoreEntry = await _client.GetTokenStoreEntry(jwt, attribute);
            }

            return(tokenStoreEntry.AccessToken);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TokenItem"/> class.
        /// </summary>
        /// <param name="member">The member.</param>
        /// <param name="attr">The attr.</param>
        /// <param name="valueType">Type of the value.</param>
        public TokenItem(TokenMember member, TokenAttribute attr, Type valueType)
            : base(valueType)
        {
            if (member == null)
            {
                throw new ArgumentNullException("member");
            }

            _name    = attr.Name;
            _aliases = attr.Aliases;

            _member        = member;
            _typeConverter = attr.TypeConverter ?? member.DefaultTypeConverter;

            if (valueType != null && !_member.DataType.IsAssignableFrom(valueType))
            {
                throw new ArgumentException("valueType must be assignable to datatype of member", "valueType");
            }
        }
Ejemplo n.º 13
0
        public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering)
        {
            if (isAltering)
            {
                var sortOption = String.IsNullOrEmpty(attribute.Value) ? 'A' : attribute.Value[0];

                switch (sortOption)
                {
                case 'A':
                    currentValues.Sort(StringComparer.OrdinalIgnoreCase);
                    currentValues.Reverse();
                    break;

                case 'D':
                    currentValues.Sort(StringComparer.OrdinalIgnoreCase);
                    break;
                }
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Retrieve an access token for the specified resource (e.g. MS Graph)
        /// </summary>
        /// <param name="attribute">TokenAttribute with desired resource & user's principal ID or ID token</param>
        /// <returns>JWT with audience, scopes, user id</returns>
        public async Task <string> GetAccessTokenAsync(TokenAttribute attribute)
        {
            attribute.CheckValidity();
            switch (attribute.Identity)
            {
            case TokenIdentityMode.UserFromId:
                // If the attribute has no identity provider, assume AAD
                attribute.IdentityProvider = attribute.IdentityProvider ?? "AAD";
                string signingKey           = AppSettings.Resolve(Constants.AppSettingWebsiteAuthSigningKey);
                var    easyAuthTokenManager = new EasyAuthTokenManager(EasyAuthClient, signingKey);
                return(await easyAuthTokenManager.GetEasyAuthAccessTokenAsync(attribute));

            case TokenIdentityMode.UserFromToken:
                return(await GetAuthTokenFromUserToken(attribute.UserToken, attribute.Resource));

            case TokenIdentityMode.ClientCredentials:
                return(await AadClient.GetTokenFromClientCredentials(attribute.Resource));
            }

            throw new InvalidOperationException("Unable to authorize without Principal ID or ID Token.");
        }
Ejemplo n.º 15
0
        public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering)
        {
            if (isAltering)
            {
                for (var i = 0; i < currentValues.Count; i++)
                {
                    int currentIntValue;
                    if (int.TryParse(currentValues[i], out currentIntValue) == false)
                    {
                        continue;
                    }

                    int attributeIntValue;
                    if (int.TryParse(attribute.Value, out attributeIntValue) == false)
                    {
                        continue;
                    }

                    currentValues[i] = (currentIntValue + attributeIntValue).ToString();
                }
            }
        }
 public override Task <IGraphServiceClient> GetMSGraphClientAsync(TokenAttribute attribute)
 {
     return(Task.FromResult(_client));
 }
Ejemplo n.º 17
0
        public async Task <EasyAuthTokenStoreEntry> GetTokenStoreEntry(JwtSecurityToken jwt, TokenAttribute attribute)
        {
            // Send the token to the local /.auth/me endpoint and return the JSON
            string meUrl = _baseUrl + $".auth/me?provider={attribute.IdentityProvider}";

            using (var request = new HttpRequestMessage(HttpMethod.Get, meUrl))
            {
                request.Headers.Add("x-zumo-auth", jwt.RawData);
                _log.Verbose($"Fetching user token data from {meUrl}");
                using (HttpResponseMessage response = await _httpClient.SendAsync(request))
                {
                    _log.Verbose($"Response from '${meUrl}: {response.StatusCode}");
                    if (!response.IsSuccessStatusCode)
                    {
                        string errorResponse = await response.Content.ReadAsStringAsync();

                        throw new InvalidOperationException($"Request to {_baseUrl} failed. Status Code: {response.StatusCode}; Body: {errorResponse}");
                    }
                    var responseString = await response.Content.ReadAsStringAsync();

                    return(JsonConvert.DeserializeObject <EasyAuthTokenStoreEntry>(responseString));
                }
            }
        }
Ejemplo n.º 18
0
 public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering)
 {
 }