Authorization

# Introduction

A key feature of MIRACL Trust SSO is that it is possible to create filters so that only authorized individuals can attempt to login. There are 3 ways of approaching this:

  1. An LDAP server. You can enter the details of your server in a config file such as /etc/miracl-sso/integrations/ldap.yaml. The ldap config file should then be listed in the includes found in /etc/miracl-sso/config.yaml and the query invoked in the authorize subsection in the individual SP files. Multiple servers and queries can be set up, then each SP file can make use of the appropriate queries.

  2. An API request. You can enter its details in a config file such as /etc/miracl-sso/integrations/api.yaml. Then this file should be listed in the includes of the service found in /etc/miracl-sso/config.yaml and invoked from the autorize subsection of the service provider you’d like to authorize with this API. Multiple API request could be configured, then each SP file can make use or the appropriate ones.

  3. For more basic needs, a simple regex filter can be enough and allow only attempted logins from users in specific email domains for example. This is done directly in the individual SP configuratin and does not require additional authorization settings.

    Both API and LDAP configuration are set up in the authorization section of the idp. All authorization rules are invoked in the authorize subsection in the relevant SP configuration file and could be combined per the SP needs:

    sp:
      example_sp:
        description: An example SAML service provider configuration
        relay_state: /
        login_url: http://example.com/login
        logout_url: http://example.com/logout
        metadata: >-
        authorize:
        - - email: "^[^@]+@example.com$"
          - ldap: ldap_profile
    

    In this example only users who are authorized to the ldap_profile and have emails with example.com domain are allowed to login.

    Please note that in the authentication platform all identities are converted to lowercase. Hence, if you assign an email containing uppercase characters to a Windows user in Active Directory the user is required to authenticate with the lowercase equivalent. For example John.Smith@example.com needs to authenticate as john.smith@example.com.

  4. For testing purposes MIRACL Trust SSO allows to specify an SP authorize section to a boolean value. If set to true (as in the following example), no authorization is applied and every user is allowed to be authenticated. If set to false - noone is allowed to authenticate.

    sp:
      example_sp:
        ......
        authorize: true
    

    We suggest you to use this feature only for testing purposes and do not forget to specify the authorization due to your specific needs when goes to production.

# Basic Regular Expression Domain Filtering

The following example shows an OR list of regex domains, meaning that users from any of the three listed domains are authorized to attempt login. For the YAML OR list note that each expression is a double dash. For the json OR list, each expression is within its own set of square brackets:

authorize:
- - email: "^[^@]+@test.com$"
- - email: "^[^@]+@example.com$"
- - email: "^[^@]+@mycompany.co.uk$"

The following example is an AND query (in yaml the first expression is a double dash and the second is a single dash. While in JSON both expressions are within the one set of square brackets). This allows, for example, only authorized users from a particular email domain AND who are also in a particular LDAP group (configuring LDAP is explained in more detail below).

authorize:
- - email: "^[^@]+@example.com$"
  - ldap: ldap_profile

You can create as complicated rules as your needs are. Here is an SP authorize subsection which authorizes users from example.com domain which have accounts in the ldap_profile or users from miracl.com domain with valid authorization request from the api named local.

authorize:
- - email: "^[^@]+@example.com$"
  - ldap: ldap_profile
- - email: "^[^@]+@miracl.com$"
  - api: local

# API Usage

There are cases when the authorization needs to be specified from an API request. In your API config file (/etc/miracl-sso/api.yaml) you can enter your api details. Here is the full list of the params you could specify. Only endpoint is mandatory.

authorization:
  api:
    "local":
      endpoint: http://127.0.0.1:8002/user
      request_headers:
        "Authorization": "Basic <SECRET>"
        "X-Forwarded-For": "http://127.0.0.1:8002/user"
      request_body: "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html mlns=\"http://www.w3.org/1999/xhtml\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><title>Authorize</title></head><body><div>Authorize user <input id=\"user_id\" name=\"user_id\">{{.UserID}}</input> with email <input id=\"email\" name=\"email\">{{.Email}}</input></div></body></html>"
      method: GET
      response_attributes:
        - displayName
        - sn

A request with the specified request_headers and request_body is sent to the endpoint. The headers are not mandatory but they could be used to verify the request as the example is doing. The body contains an html template with the UserID and Email which need to be authorized and could be formatted per the request needs. method accepts either GET or POST depending on what http method request should be done.

Here is a sample reponse from the API request:

{
  "user_id": "john.smith@example.com",
  "email": "john.smith@example.com",
  "attributes": {
    "displayName":["John Smith"],
    "sn": ["Smith"],
    "title": ["Senior Developer", "Freelancer"]
  }
}

The user_id and email should correspond to the request UserID and Email. Notice the attributes in the response. You could require specific attributes in the API response_attributes property. If they do not exist in the response, the user is not authorized and is not allowed to proceed further. So this is a valid response for the configuration above.

# Basic LDAP Usage

In your LDAP config file (/etc/miracl-sso/ldap.yaml) you can enter your ldap server details:

authorization:
  ldap:
    server:
      ldap_server:
        method: plain
        address: 127.0.0.1:389
        user: cn=Directory Manager
        password: <LDAP_PASSWORD>
    query:
      ldap_profile:
        server: ldap_server
        search:
        - dn: ou=people,dc=example,dc=com
          filter: (mail={{.Email}})

Within the server subsection it is possible to add more than one LDAP server and then have one or more queries for each server, within the query subsection. As an example you could add a query for ’ldap_profile2’ which also queries the ’ldap_server’ server:

query:
 ldap_profile:
  server: ldap_server
  search:
  - dn: ou=people,dc=example,dc=com
    filter: (mail={{.Email}})
 ldap_profile2:
  server: ldap_server
  search:
  - dn: ou=dept2,dc=example,dc=com
    filter: (mail={{.Email}})

The “filter” in the above example programmatically picks up the current user’s email address from the IdP and checks it with the ‘mail’ attribute on the LDAP server.

# Advanced LDAP Usage

Some Service Providers have particular requirements for the extraction of LDAP attributes (such as ImmutableID for Office 365).

With MIRACL Trust SSO there are two types of attributes that can be passed:

  1. Attributes which are programmatically picked up from the SSO IdP to pass on to the SP. In an attribute statement these are passed as variables within the AttributeValue tags. Examples being <AttributeValue>{{.NameID}}</AttributeValue> or <AttributeValue>{{.MetadataEntityID}}</AttributeValue>. An explanation (along with a table of available variables) of how this is done can be found in the Generic Setup Instructions.

  2. Attributes which are extracted from an LDAP server before being passed on to the SP. In an attribute statement these are passed as {{AttrVal}} variables within the AttributeValue tags. An example being <AttributeValue>{{AttrVal "uid" 0 "" .Attributes}}</AttributeValue>. This is explained in more detail below.

The use case here is as follows:

  1. For the user attempting to register/login, grab an LDAP attribute from the LDAP server.

  2. The MIRACL Trust SSO passes this value to the Service Provider (which should be expecting to receive the custom LDAP attribute for the user in order to match with its own records).

  3. The Service Provider checks that the value passed for the user matches what they have.

These steps are managed thus:

  1. In the ldap config file (/etc/miracl-sso/integrations/ldap.yaml) the attributes to be used are made available in an ldap query:

    authorization:
      ldap:
        server:
          ldap_server:
            method: plain
            address: 203.0.113.1:389
            user: cn=admin,dc=ldap,dc=example,dc=com
            password: <LDAP_PASSWORD>
        query:
          ldap_profile:
            server: ldap_server
            search:
            - dn: ou=dept1,dc=ldap,dc=example,dc=com
              filter: "(mail={{.UserID}})"
              attributes:
              - departmentNumber
    
  2. In the SP config file (/etc/miracl-sso/service_providers/example_sp.yaml), a profile section should be created with an attribute subsection. This names the attribute according to what the SP is expecting (dept_code in this example), and passes the LDAP attribute (departmentNumber) as extracted in step 1 (note the use of AttrVal which identifies that this is an LDAP atttribute). The ldap query is invoked in the authorize subsection, while the attribute profile is invoked in the profile subsection:

    profile:
      attribute:
        example_sp: >-
          <AttributeStatement>
            <Attribute Name="dept_code">
              <AttributeValue>{{AttrVal "departmentNumber" 0 "" .Attributes}}</AttributeValue>
            </Attribute>
          </AttributeStatement>
    sp:
      example_sp:
        description: An example SAML service provider configuration
        relay_state: "/"
        login_url: http://example.com/login
        logout_url: http://example.com/logout
        metadata: >-
          <SP_METADATA>
        authorize:
        - - ldap: ldap_profile
        profile:
          attribute: example_sp