First, create a new Single Sign-On authentication under User & Authentication. As of version 7.0.6, the GUI does not specify ports and does not let you change them either. To work around this, use the CLI. Default ports used by the captive portal are TCP/1000 and TCP/1003 for HTTP and HTTPS traffic respectively.

You can find the different URLs about the IdP in Keycloak, in the relevant realm, under Realm Settings, then click on “SAML 2.0 Identity Provider Metadata”. The idp-entity-id is the value of entityID on the first line. The idp-single-sign-on-url and idp-single-logout-url are the same on Keycloak and you can use the value of the binding urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST.

config user saml
    edit "SAML_sso.example.org"
        set entity-id "http://10.0.0.1:1000/remote/saml/metadata/"
        set single-sign-on-url "https://10.0.0.1:1003/remote/saml/login/"
        set single-logout-url "https://10.0.0.1:1003/remote/saml/logout/"
        set idp-entity-id "https://sso.example.org/auth/realms/sso.example.org"
        set idp-single-sign-on-url "https://sso.example.org/auth/realms/sso.example.org/protocol/saml"
        set idp-single-logout-url "https://sso.example.org/auth/realms/sso.example.org/protocol/saml"
        set idp-cert "sso.example.org"
        set user-name "username"
        set group-name "group"
        set digest-method sha256
    next
end

While you are in Keycloak, create a new client with protocol saml. Set Client ID to the value of entity-id and leave Client SAML Endpoint empty. Click save. Then set the following settings:

  • set a friendly name
  • disable “Client Signature Required”
  • set the values of single-sign-on-url and signle-logout-url as Valid Redirect URIs
  • set the value of entity-id as Master SAML Processing URL
  • set the value of single-sign-on-url for Assertion Consumer Service POST and Redirect Binding URLs
  • set the value of single-logout-url for Logout Service POST and Redirect Binding URLs

Then we need to send the username as an attribute in the SAML assertion. Go to the Mappers tab, click create. Select User Property in Mapper Type. Set username for all the remining fields. Click save.

We also need to send the list of groups in the SAML assertion. In the Mappers tab, click create. Select Group list in Mapper Type. Set group for all the remaining fields. Disable Single Group Attribute and Full group path. Click save.

Back to the Fortigate. Create a user group. Under User & Authentication, go to User Groups, click Create New. Set a friendly name. Under Remote Groups, click Add and select the SAML authentication you created in the previous step. Specify the group of users who can authenticate.

config user group
    edit "SAML_sso.example.org"
        set member "SAML_sso.example.org"
        config match
            edit 1
                set server-name "SAML_sso.example.org"
                set group-name "firewall-users"
            next
        end
    next
end

Now, in your firewall policies, you can add the group created in the previous step to the source field. The firewall will redirect your users to the captive portal, then to the SSO login page.

If you want to intercept SSL, configure your policies in proxy mode and set a SSL inspection profile configured to intercept. Remember to use a CA trusted by your clients for the inspection profile.

You should also use a certificate trusted by your clients for the captive portal. You can set it using the CLI:

config system global
    set admin-server-cert "fwirewall.example.org"
end

By default, user authentication is linked to the IP address of the user for 5 minutes, refreshed each time packets go through a policy.