Authorization for Unenrolled Students

Recently, a use case has surfaced where access to students is authorized based not only on the presence of an enrollment (captured in the studentSchoolAssociations resource), but also through services provided to the student (captured in resources derived from  StudentEducationOrganizationResponsibilityAssociation). The presence of either of these associations with a student should grant access to the API client.

These instructions are provided for Ed-Fi ODS / API for Suite 3 v5.3 and above. Instructions may not exactly apply to older versions and will need some adjustments. 

The general approach for authorization involves adding a UNION to the "EducationOrganization To Student " view to combine the education organization responsibility associations with the ones derived from the StudentSchoolAssociation table, in a new view using the "UsingEnrollmentsAndResponsibility" authorization path modifier, as follows:

CREATE OR ALTER VIEW [auth].[EducationOrganizationIdToStudentUSIUsingEnrollmentsAndResponsibility]
    WITH SCHEMABINDING AS
    -- EdOrgtoEdOrg to Student (through school enrollment)
   SELECT  edOrgs.SourceEducationOrganizationId, ssa.StudentUSI
    FROM    auth.EducationOrganizationIdToEducationOrganizationId edOrgs
        INNER JOIN edfi.StudentSchoolAssociation ssa
            ON edOrgs.TargetEducationOrganizationId = ssa.SchoolId
    GROUP BY edOrgs.SourceEducationOrganizationId, ssa.StudentUSI
    UNION
    --  EdOrgtoEdOrg to Student (through  EdOrg-level Responsibility)
    SELECT  edOrgs.SourceEducationOrganizationId, seora.StudentUSI
    FROM    auth.EducationOrganizationIdToEducationOrganizationId edOrgs
            INNER JOIN edfi.StudentEducationOrganizationResponsibilityAssociation seora
                ON edOrgs.TargetEducationOrganizationId = seora.EducationOrganizationId
    GROUP BY edOrgs.SourceEducationOrganizationId, seora.StudentUSI
GO

Additionally, a new authorization strategy ("RelationshipsWithStudentsOnlyUsingEnrollmentsAndResponsibility") will need to be added to the EdFi_Security database, to the AuthorizationStrategies table in the same vein as the "RelationshipsWithStudentsOnlyThroughResponsibility" record, shown below:

C# classes will also need to be added, using any classes with the text "ThroughResponsibility" in the class names or literal text as a reference to create the "UsingEnrollmentsAndResponsibility" versions. In the class shown below, the term "ThroughResponsibility" is used in both the class name and as a literal near the end of the constructor method:

    public class RelationshipsWithStudentsOnlyThroughResponsibilityAuthorizationStrategy<TContextData>
        : RelationshipsAuthorizationStrategyBase<TContextData>
        where TContextData : RelationshipsAuthorizationContextData, new()
    {
        public RelationshipsWithStudentsOnlyThroughResponsibilityAuthorizationStrategy(IConcreteEducationOrganizationIdAuthorizationContextDataTransformer<TContextData> concreteEducationOrganizationIdAuthorizationContextDataTransformer)
            : base(concreteEducationOrganizationIdAuthorizationContextDataTransformer) { }

        protected override void BuildAuthorizationSegments(
            AuthorizationBuilder<TContextData> authorizationBuilder,
            string[] authorizationContextPropertyNames)
        {
            authorizationContextPropertyNames
               .Where(pn => PersonEntitySpecification.IsPersonIdentifier(pn, "Student"))
               .ForEach(pn => authorizationBuilder.ClaimsMustBeAssociatedWith(pn, "ThroughResponsibility"));
        }
    }

Additionally, a new filter configurator RelationshipsWithStudentsOnlyUsingEnrollmentsAndResponsibilityAuthorizationStrategyFilterConfigurator will be needed and can be based on the existing one for "ThroughResponsibility":

    public class RelationshipsWithStudentsOnlyThroughResponsibilityAuthorizationStrategyFilterConfigurator
        : INHibernateFilterConfigurator
    {
        /// <summary>
        /// Gets the NHibernate filter definitions and a functional delegate for determining when to apply them.
        /// </summary>
        /// <returns>A read-only list of filter application details to be applied to the NHibernate configuration and entity mappings.</returns>
        public IReadOnlyList<FilterApplicationDetails> GetFilters()
        {
            var filters = new List<FilterApplicationDetails>
                          {
                              // Local Education Agency/School to Student relationships (through StudentEducationOrganizationAssociation)
                              RelationshipsAuthorizationFilters.LocalEducationAgencyIdToStudentUSIThroughResponsibility,
                              RelationshipsAuthorizationFilters.SchoolIdToStudentUSIThroughResponsibility
                          };

            return filters;
        }
    }

To find the other artifacts to copy/paste/modify, search the code for "ThroughResponsibility" text, the results of which is shown below (the remaining additions appear to be limited to the RelationshipAuthorizationFilters.cs class):

After you have setup all the above, update EdFi_Security  database to define claim set specific authorization strategy overrides to use the new "RelationshipsWithStudentsOnlyUsingEnrollmentsAndResponsibility" authorization strategy for resource actions of interest. See How To: Configure Claim Sets#DefineClaimSetSpecificAuthorizationStrategyOverrideforaResourceAction for details.