示例#1
0
        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));
        }
示例#2
0
 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();
            }
        }
示例#4
0
        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));
            }
        }
示例#5
0
        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));
        }
示例#9
0
        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));
        }
示例#10
0
            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));
 }
示例#13
0
 public DbApiKeyQuery(ApiKeyContext context, ILogger <DbApiKeyQuery> logger)
 {
     _context = context ?? throw new ArgumentNullException(nameof(context));
 }