en:tech:userfiltering

User filtering at the Shibboleth SP side

If you are looking for a method to restrict user access to your resources, there are at least two means how to achieve it. The first way is using a logic implemented in your application. The second way is using a filter in Shibboleth SP.

The first way offers a higher level of flexibility and comfort for users. You can also inform users why the access has been restricted, etc. The second way is much simpler to implement and in a number of cases the only one possible if you cannot modify the application. In both cases, you could utilize entity categories.

Entity attributes definition

Entity attributes are listed in federation metadata. In eduID.cz federation, there are IdP categories and a few other ones. Those attributes might be mapped in Shibboleth SP similarly to users' attributes released by IdPs. To utilize entity categories, it is required to set a prefix for metadata attributes in ApplicationDefaults element (or ApplicationOverride element) within shibboleth2.xml configuration file like so:

<ApplicationDefaults entityID="https://example.org/shibboleth/"
    metadataAttributePrefix="md_">

Say, there is the following attribute defined with an entity:

<mdattr:EntityAttributes>
    <saml:Attribute Name="http://macedir.org/entity-category" 
        NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
        <saml:AttributeValue>http://eduid.cz/uri/idp-group/library</saml:AttributeValue>
    </saml:Attribute>
</mdattr:EntityAttributes>

Then, we can define attribute mapping in attribute-map.xml this way:

<Attribute name="http://macedir.org/entity-category" id="entityCategory" />

As a result the above defined attribute value is available as a md_entityCategory variable. In case you have source codes of your application, you can implement access control within the application yourself. Alternatively Shibboleth SP functionality is here to help.

To check what entity category value is passed to applications, use our testing SP at https://attributes.eduid.cz/.

Access control using Shibboleth SP

The rules designated for access control are quite complex and details are described in documentation.

In Apache, you just need to define a directory (/limit/access)) to which you would like to restrict access and where the rules defining authorization are placed (/path/to/ac.xml):

<Directory /limit/access>
    AuthType shibboleth
    ShibRequestSetting requireSession 1
    ShibAccessControl /path/to/ac.xml 
</Directory>

Include filter

In a document describing IdP categories an include filter is given. The example lists what group of users from various IdPs are accepted as a Research & Education community. The filter in a pseudocode follows.

(idp_category='university' and ((affiliate='employee') or (affiliate='faculty') or (affiliate='member') or (affiliate='student') or (affiliate='staff'))) or
(idp_category='avcr' and (affiliate='member')) or
(idp_category='library' and (affiliate='employee')) or
(idp_category='hospital' and (affiliate='employee')) or
(idp_category='other' and ((affiliate='employee') or (affiliate='member')))

Implementation in Shibboleth SP configuration (the content of /path/to/ac.xml):

<AccessControl type="edu.internet2.middleware.shibboleth.sp.provider.XMLAccessControl">
  <OR>
    <AND>
      <Rule require="md_entityCategory">http://eduid.cz/uri/idp-group/university</Rule>
      <OR>
        <RuleRegex require="affiliation">^employee@.+\.cz$</RuleRegex>
        <RuleRegex require="affiliation">^faculty@.+\.cz$</RuleRegex>
        <RuleRegex require="affiliation">^member@.+\.cz$</RuleRegex>
        <RuleRegex require="affiliation">^student@.+\.cz$</RuleRegex>
        <RuleRegex require="affiliation">^staff@.+\.cz$</RuleRegex>
      </OR>
    </AND>
    <AND>
      <Rule require="md_entityCategory">http://eduid.cz/uri/idp-group/avcr</Rule>
      <RuleRegex require="affiliation">^member@.+\.cz$</RuleRegex>    
    </AND>
    <AND>
      <Rule require="md_entityCategory">http://eduid.cz/uri/idp-group/library</Rule>
      <RuleRegex require="affiliation">^employee@.+\.cz$</RuleRegex>
    </AND>
    <AND>
      <Rule require="md_entityCategory">http://eduid.cz/uri/idp-group/hospital</Rule>
      <RuleRegex require="affiliation">^employee@.+\.cz$</RuleRegex>    
    </AND>
    <AND>
      <Rule require="md_entityCategory">http://eduid.cz/uri/idp-group/cesnet</Rule>
      <OR>
        <RuleRegex require="affiliation">^employee@.+\.cz$</RuleRegex>    
        <RuleRegex require="affiliation">^member@.+\.cz$</RuleRegex>    
      </OR>
    </AND>
  </OR>
</AccessControl>

Exclude filter

An alternative to an include filter is an exclude filter. Note that the exclude filter is not a simple inversion of the include filter. It does not deal with users with multiple affiliation values such as affiliate and employee at once. Moreover, this way does not handle creation of a new category at IdPs – users from newly created category would be granted access. You should not use the exclude filter if you are not really sure what does this mean.

not (
  (affiliation=='alum') or
  (idp_category=='library' and (not affiliation=='employee'))
)

Implementation in Shibboleth SP configuration (the content of /path/to/ac.xml):

<AccessControl type="edu.internet2.middleware.shibboleth.sp.provider.XMLAccessControl">
  <NOT>
    <OR>
      <RuleRegex require="affiliation">^alumn@.+\.cz$</RuleRegex>
      <AND>      
        <Rule require="md_entityCategory">http://eduid.cz/uri/idp-group/library</Rule>
        <NOT>
          <RuleRegex require="affiliation">^employee@.+\.cz$</RuleRegex>    
        </NOT>
      </AND>      
    </OR>
  </NOT> 
</AccessControl>

Diagnostic page

In a basic Shibboleth SP configuration, a user is shown only a basic webserver error message when access is forbidden.

A service administrator has only few options to find out what went wrong without close cooperation with the user. Shibboleth SP does not log attribute values even when set to DEBUG mode. Apache logs just an information about denying access to a document:

2001:718:1:6::1:1 - uid@cesnet.cz [29/Sep/2014:16:19:46 +0200] "GET /ac2/ HTTP/1.1" 403 235

We have designed a very simple web page that helps informing users about restricting access in a user friendly way. A simple script allowing administrators to tune access control rules is also available. These materials including detailed information are kept in a CESNET repository at GitHub.

After cloning the repository or downloading corresponding web pages accessError.html and accessError.php, you have to inform Shibboleth SP what page to show if a user is rejected due to unsufficient access rights. This is set using access attribute within <Errors> element in shibboleth2.xml configuration file:

<Errors supportContact="admin@example.cz"
   logoLocation="/shibboleth-sp/logo.jpg"
   styleSheet="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"
   access="/path/to/accessError.html"
/>

In the code of accessError.html page is a link to diagnostic script. In our example, the address is set to /my-app/diagnose which we need to configure in Apache:

<Location /my-app/diagnose>
    AuthType shibboleth
    ShibRequestSetting requireSession 1
    require valid-user
</Location>

As long as the user is not allowed to access a page due to insufficient rights, accessError.html page is show.

Clicking the „Diagnose“ button redirects the user to a diagnostic page that logs all the environment variables ($_SERVER) to a defined file (in a default configuration /tmp/shib-access-error.log file). The problem is assigned an identifier shown at the page.

Knowing this identifier, the service administrator is able to diagnose environment variables of the session. After comparing session attributes and access control rules (ac.xml file as stated above), a reason for the error should be easily found.

The diagnostic page and script used in the examples above is just a sample how to proceed. We strongly recommend not to use it without further investigation of how it works. The page and script should be reviewed before usage as some variables such as a log file or administrator's e-mail should be set.

Last modified:: 2017/02/10 07:02