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)); }
public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering) { if (isAltering == false) { attribute.Token.ItemSeparator = attribute.Value; } }
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)); }
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)); }
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); } }
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); }
/// <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"); } }
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; } } }
/// <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."); }
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)); }
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)); } } }
public override void Process(TokenAttribute attribute, List <string> currentValues, bool isAltering) { }