public async Task <IHttpActionResult> PostAsync([FromBody] TokenInfoRequest tokenInfoRequest) { // see https://tools.ietf.org/html/rfc7662#section-2.2 for oauth token_info spec if (tokenInfoRequest == null || tokenInfoRequest.Token == null || !Guid.TryParse(tokenInfoRequest.Token, out Guid accessToken)) { return(BadRequest("Invalid token")); } var oAuthTokenClient = (await _tokenClientRepo.GetClientForTokenAsync(accessToken)).FirstOrDefault(); if (oAuthTokenClient == null) { return(NotFound()); } ApiKeyContext apiContext = _apiKeyContextProvider.GetApiKeyContext(); // must be able to see my specific items ie vendor a cannot look at vendor b if (oAuthTokenClient.Key != apiContext.ApiKey) { return(Unauthorized()); } TokenInfo tokenInfo = await _tokenInfoProvider.GetTokenInfoAsync(apiContext); HttpContext.Current.Response.Headers.Add("Cache-Control", "no-cache"); return(Ok(tokenInfo)); }
public static TokenInfo Create(ApiKeyContext apiKeyContext, IList <EducationOrganizationIdentifiers> educationOrganizationIdentifiers) { return(new TokenInfo { Active = true, ApiKey = apiKeyContext.ApiKey, NamespacePrefixes = apiKeyContext.NamespacePrefixes, AssignedProfiles = apiKeyContext.Profiles, StudentIdentificationSystem = apiKeyContext.StudentIdentificationSystemDescriptor, EducationOrganizations = educationOrganizationIdentifiers .Select( x => new { education_organization_id = x.EducationOrganizationId, state_education_organization_id = x.StateEducationAgencyId, local_education_agency_id = x.LocalEducationAgencyId, school_id = x.SchoolId, community_organization_id = x.CommunityOrganizationId, community_provider_id = x.CommunityProviderId, post_secondary_institution_id = x.PostSecondaryInstitutionId, university_id = x.UniversityId, teacher_preparation_provider_id = x.TeacherPreparationProviderId, name_of_institution = x.NameOfInstitution, type = x.FullEducationOrganizationType }) .ToArray() }); }
/// <summary> /// Initializes a new instance of the <see cref="EdFiAuthorizationContext"/> class using the principal, resource, action and Ed-Fi authorization context data. /// </summary> /// <param name="apiKeyContext">Direct information about the current API client, typically presented as claims.</param> /// <param name="principal">The <see cref="ClaimsPrincipal" /> containing the claims.</param> /// <param name="resourceClaimUris">The URI representations of the resource claims being authorized.</param> /// <param name="action">The action being taken on the resource.</param> /// <param name="data">An object containing the data available for authorization which implements one of the /// model interfaces (e.g. IStudent).</param> public EdFiAuthorizationContext( ApiKeyContext apiKeyContext, ClaimsPrincipal principal, string[] resourceClaimUris, string action, object data) { Preconditions.ThrowIfNull(apiKeyContext, nameof(apiKeyContext)); Preconditions.ThrowIfNull(resourceClaimUris, nameof(resourceClaimUris)); Preconditions.ThrowIfNull(action, nameof(action)); ApiKeyContext = apiKeyContext; Principal = principal; Data = data; resourceClaimUris.ForEach( resourceClaimUri => Resource.Add(new Claim(ClaimsName, resourceClaimUri))); Action.Add(new Claim(ClaimsName, action)); if (data != null) { Type = data.GetType(); } }
public async Task <TokenInfo> GetTokenInfoAsync(ApiKeyContext apiContext) { using (var session = _sessionFactory.OpenStatelessSession()) { string edOrgIds = string.Join(",", apiContext.EducationOrganizationIds); var tokenInfoEducationOrganizationData = await session.CreateSQLQuery(string.Format(EdOrgIdentifiersSql, edOrgIds)) .SetResultTransformer(Transformers.AliasToBean <TokenInfoEducationOrganizationData>()) .ListAsync <TokenInfoEducationOrganizationData>(CancellationToken.None); return(TokenInfo.Create(apiContext, tokenInfoEducationOrganizationData)); } }
public static TokenInfo Create(ApiKeyContext apiKeyContext, IList <TokenInfoEducationOrganizationData> tokenInfoData) { var dataGroupedByEdOrgId = tokenInfoData .GroupBy( x => (x.EducationOrganizationId, x.NameOfInstitution, x.Discriminator), x => { string type = x.AncestorDiscriminator.Split('.')[1]; string idPropertyName = Inflector.AddUnderscores($"{type}Id"); return(new { PropertyName = idPropertyName, EducationOrganizationId = x.AncestorEducationOrganizationId }); }); var tokenInfoEducationOrganizations = new List <OrderedDictionary>(); foreach (var grouping in dataGroupedByEdOrgId) { var entry = new OrderedDictionary(); var(educationOrganizationId, nameOfInstitution, discriminator) = grouping.Key; // Add properties for current claim value entry["education_organization_id"] = educationOrganizationId; entry["name_of_institution"] = nameOfInstitution; entry["type"] = discriminator; // Add related ancestor EducationOrganizationIds foreach (var ancestorEducationOrganization in grouping) { entry[ancestorEducationOrganization.PropertyName] = ancestorEducationOrganization.EducationOrganizationId; } tokenInfoEducationOrganizations.Add(entry); } return(new TokenInfo { Active = true, ApiKey = apiKeyContext.ApiKey, NamespacePrefixes = apiKeyContext.NamespacePrefixes.ToArray(), AssignedProfiles = apiKeyContext.Profiles.ToArray(), StudentIdentificationSystem = apiKeyContext.StudentIdentificationSystemDescriptor, EducationOrganizations = tokenInfoEducationOrganizations.ToArray() }); }
protected override void Act() { _contextStorage = new HashtableContextStorage(); var settingProvider = new ApiKeyContextProvider(_contextStorage); settingProvider.SetApiKeyContext( new ApiKeyContext( SuppliedApiKey, SuppliedClaimsetName, _suppliedEducationOrganizationIds, _suppliedNamespacePrefixes, _suppliedProfiles, SuppliedStudentIdentificationSystemDescriptor, _suppliedCreatorOwnershipTokenId, _suppliedOwnershipTokenIds)); var gettingProvider = new ApiKeyContextProvider(_contextStorage); _actualApiKey = gettingProvider.GetApiKeyContext() .ApiKey; _actualClaimsetName = gettingProvider.GetApiKeyContext() .ClaimSetName; _actualEducationOrganizationIds = gettingProvider.GetApiKeyContext() .EducationOrganizationIds; _actualNamespacePrefixes = gettingProvider.GetApiKeyContext() .NamespacePrefixes; _actualProfiles = gettingProvider.GetApiKeyContext() .Profiles; _actualStudentIdentificationSystemDescriptor = gettingProvider.GetApiKeyContext().StudentIdentificationSystemDescriptor; _actualCreatorOwnershipTokenId = gettingProvider.GetApiKeyContext().CreatorOwnershipTokenId; _actualOwnershipTokenIds = gettingProvider.GetApiKeyContext().OwnershipTokenIds; settingProvider.SetApiKeyContext(_suppliedApiKeyContext); _actualApiKeyContext = gettingProvider.GetApiKeyContext(); }
public async Task <TokenInfo> GetTokenInfoAsync(ApiKeyContext apiContext) { using (var session = _sessionFactory.OpenStatelessSession()) { var columns = await session.CreateSQLQuery(ColumnsSql) .ListAsync <string>(CancellationToken.None); string edOrgIds = string.Join(",", apiContext.EducationOrganizationIds); string whereClause = string.Join(" or ", columns.Select(x => $"{x} in ({edOrgIds})")); var educationOrganizationIdentifiers = await session.CreateSQLQuery(string.Format(EdOrgIdentifiersSql, whereClause)) .SetResultTransformer(Transformers.AliasToBean <EducationOrganizationIdentifiers>()) .ListAsync <EducationOrganizationIdentifiers>(CancellationToken.None); return(TokenInfo.Create(apiContext, educationOrganizationIdentifiers)); } }
/// <summary> /// Initializes a new instance of the <see cref="EdFiAuthorizationContext"/> class using the principal, resource, action and Ed-Fi entity type. /// </summary> /// <param name="apiKeyContext">Direct information about the current API client, typically presented as claims.</param> /// <param name="principal">The <see cref="ClaimsPrincipal" /> containing the claims.</param> /// <param name="resourceClaimUris">The URI representations of the resource claims being authorized.</param> /// <param name="action">The action being taken on the resource.</param> /// <param name="type">The entity type which implements one of the model interfaces (e.g. IStudent) which is the subject of a multiple-item request.</param> public EdFiAuthorizationContext( ApiKeyContext apiKeyContext, ClaimsPrincipal principal, string[] resourceClaimUris, string action, Type type) { Preconditions.ThrowIfNull(apiKeyContext, nameof(apiKeyContext)); Preconditions.ThrowIfNull(resourceClaimUris, nameof(resourceClaimUris)); Preconditions.ThrowIfNull(action, nameof(action)); Preconditions.ThrowIfNull(type, nameof(type)); ApiKeyContext = apiKeyContext; Principal = principal; Type = type; resourceClaimUris.ForEach( resourceClaimUri => Resource.Add(new Claim(ClaimsName, resourceClaimUri))); Action.Add(new Claim(ClaimsName, action)); }
private async Task <IActionResult> GetTokenInformation(TokenInfoRequest tokenInfoRequest) { if (!_isEnabled) { return(NotFound()); } // see https://tools.ietf.org/html/rfc7662#section-2.2 for oauth token_info spec if (tokenInfoRequest == null || tokenInfoRequest.Token == null || !Guid.TryParse(tokenInfoRequest.Token, out Guid accessToken)) { return(BadRequest(ErrorTranslator.GetErrorMessage("Invalid token"))); } var oAuthTokenClient = (await _tokenClientRepo.GetClientForTokenAsync(accessToken)).FirstOrDefault(); if (oAuthTokenClient == null) { return(NotFound()); } ApiKeyContext apiContext = _apiKeyContextProvider.GetApiKeyContext(); // must be able to see my specific items ie vendor a cannot look at vendor b if (oAuthTokenClient.Key != apiContext.ApiKey) { return(Unauthorized()); } var tokenInfo = await _tokenInfoProvider.GetTokenInfoAsync(apiContext); Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue { NoCache = true }; return(Ok(tokenInfo)); }
protected override void Arrange() { // Initialize dependencies const string suppliedClaimSetName = "claimSetName"; var apiKeyContext = new ApiKeyContext( "apiKey", suppliedClaimSetName, _suppliedEducationOrganizationIds, _suppliedNamespacePrefixes, _suppliedProfiles, null, null, null); _apiKeyContextProvider = A.Fake <IApiKeyContextProvider>(); A.CallTo(() => _apiKeyContextProvider.GetApiKeyContext()).Returns(apiKeyContext); var suppliedResourceClaims = new List <ClaimSetResourceClaimAction> { new ClaimSetResourceClaimAction { Action = new Action { ActionUri = "actionUri-1a" }, ResourceClaim = new ResourceClaim { ClaimName = "resourceClaimName1" }, AuthorizationStrategyOverrides = new List <ClaimSetResourceClaimActionAuthorizationStrategyOverrides> { new ClaimSetResourceClaimActionAuthorizationStrategyOverrides { AuthorizationStrategy = new AuthorizationStrategy { AuthorizationStrategyName = "actionUri-1a-Strategy" } } }, ValidationRuleSetNameOverride = null }, new ClaimSetResourceClaimAction { Action = new Action { ActionUri = "actionUri-1b" }, ResourceClaim = new ResourceClaim { ClaimName = "resourceClaimName1" }, AuthorizationStrategyOverrides = new List <ClaimSetResourceClaimActionAuthorizationStrategyOverrides> { new ClaimSetResourceClaimActionAuthorizationStrategyOverrides { AuthorizationStrategy = new AuthorizationStrategy { AuthorizationStrategyName = "actionUri-1b-Strategy" } } }, ValidationRuleSetNameOverride = "actionUri-1b-RuleSetName" }, new ClaimSetResourceClaimAction { Action = new Action { ActionUri = "actionUri-2" }, ResourceClaim = new ResourceClaim { ClaimName = "resourceClaimName2" }, AuthorizationStrategyOverrides = null, ValidationRuleSetNameOverride = "actionUri-2-RuleSetName" } }; _securityRepository = A.Fake <ISecurityRepository>(); A.CallTo(() => _securityRepository.GetClaimsForClaimSet(suppliedClaimSetName)).Returns(suppliedResourceClaims); }
public async Task <AuthenticationResult> GetAuthenticationResultAsync(AuthenticationHeaderValue authHeader) { ApiClientDetails apiClientDetails; try { // If there are credentials but the filter does not recognize the authentication scheme, do nothing. if (!authHeader.Scheme.EqualsIgnoreCase(AuthenticationScheme)) { _logger.Debug("Unknown auth header scheme"); return(new AuthenticationResult { AuthenticateResult = AuthenticateResult.NoResult() }); } // If the credentials are bad, set the error result. if (string.IsNullOrEmpty(authHeader.Parameter)) { _logger.Debug("Missing auth header parameter"); return(new AuthenticationResult { AuthenticateResult = AuthenticateResult.Fail("Missing auth header parameter") }); } // If there are credentials that the filter understands, try to validate them. apiClientDetails = await _oAuthTokenValidator.GetClientDetailsForTokenAsync(authHeader.Parameter); } catch (Exception e) { _logger.Error(e); return(new AuthenticationResult { AuthenticateResult = AuthenticateResult.Fail("Invalid Authorization Header") }); } if (_expectedUseSandboxValue.Value.HasValue && apiClientDetails.IsSandboxClient != _expectedUseSandboxValue.Value.Value) { string message = apiClientDetails.IsSandboxClient ? "Sandbox credentials used in call to Production API" : "Production credentials used in call to Sandbox API"; return(new AuthenticationResult { AuthenticateResult = AuthenticateResult.Fail(message) }); } var identity = _claimsIdentityProvider.GetClaimsIdentity( apiClientDetails.EducationOrganizationIds, apiClientDetails.ClaimSetName, apiClientDetails.NamespacePrefixes, apiClientDetails.Profiles.ToList()); var apiKeyContext = new ApiKeyContext( apiClientDetails.ApiKey, apiClientDetails.ClaimSetName, apiClientDetails.EducationOrganizationIds, apiClientDetails.NamespacePrefixes, apiClientDetails.Profiles, apiClientDetails.StudentIdentificationSystemDescriptor, apiClientDetails.CreatorOwnershipTokenId, apiClientDetails.OwnershipTokenIds); return(new AuthenticationResult { ClaimsIdentity = identity, ApiKeyContext = apiKeyContext }); }
private static EdFiAuthorizationContext Given_an_authorization_context_with_entity_data(ApiKeyContext apiKeyContext, object entity) { return(new EdFiAuthorizationContext(apiKeyContext, new ClaimsPrincipal(), new[] { "resource" }, "action", entity)); }
public DbApiKeyQuery(ApiKeyContext context, ILogger <DbApiKeyQuery> logger) { _context = context ?? throw new ArgumentNullException(nameof(context)); }