derricksmith / phpsaml

GLPI Plugin - SAML integration using the Onelogin SAML Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Some login problems using Keycloak

RaulGrosmam opened this issue · comments

Hello,

I've being trying to use this plugin to login on GLPI using Keycloak SAML.

But I'm facing some problems that I cant found anywhere else.

When I try to create an user using JIT, php-errors.log returns me this (using my login):

JIT Error: Unable to create user because missing claims we got the following to work with:
 *name:Raul
 *realname:Grosmam
 *_useremail:raulgrosmam@mydomain.com
 password: null all fields need to be present!

Also, if the user already exists, php-errors.log returns this:


glpiphplog.WARNING:   *** PHP Warning (2): Undefined array key "glpiactiveprofile" in /usr/share/glpi/src/Auth.php at line 1440
  Backtrace :
  index.php:103                                      Auth::redirectIfAuthenticated()
  public/index.php:73                                require()
  
glpiphplog.WARNING:   *** PHP Warning (2): Trying to access array offset on value of type null in /usr/share/glpi/src/Auth.php at line 1440
  Backtrace :
  index.php:103                                      Auth::redirectIfAuthenticated()
  public/index.php:73                                require()

These errors just happens when trying to login using Google Chrome.
When using Firefox (or even Brave Browser), it just returns:

image
And nothing else (same message appears on php-errors.log)

There's anything I can do to repair it?
I didn't put any other kind of log because I don't know what to put it in.

Many thanks!

I'm using GLPI 10.0.7 with DonutsNL 1.2.2 plugin version (using its last commit)

Hi @RaulGrosmam

Thank you for sharing the errors found.

JIT error
I noticed my logging is not reporting the received self::SCHEMA_NAME that is also a required field. I added it to the output in the latest version and it should now also be reported in the 'working with' errormessage. I am sure that that one is also missing from the received claims.

SCHEMA_NAME = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name;

Existing user
The previous might also be causing the failing auth(). Ill dive into the logic to review.

Invalid SAML response
Using my latest version you can create a 'debug' folder in the phpSaml plugin root. If you then enable debugging in the config, the plugin should dump the received phpSAML response in the debug folder for you to review. Make sure not to keep it there and remove it (dump and folder) as soon as you are finished.

Hello @DonutsNL
Many, many thanks for the response.

I've tried using your last commit (9c8eb65).

Here's my feedback

JIT Error

JIT is now able to create the user, but now it falls to the "Existing user" problem.
It creates the user, but when tries to log in, that error happens

image
User created using JIT

Existing user

Dunno if you already checked it, but the same message persists

[2023-06-27 12:08:04] glpiphplog.WARNING:   *** PHP Warning (2): Undefined array key "glpiactiveprofile" in /usr/share/glpi/src/Auth.php at line 1440
  Backtrace :
  index.php:103                                      Auth::redirectIfAuthenticated()
  public/index.php:73                                require()
  
[2023-06-27 12:08:04] glpiphplog.WARNING:   *** PHP Warning (2): Trying to access array offset on value of type null in /usr/share/glpi/src/Auth.php at line 1440
  Backtrace :
  index.php:103                                      Auth::redirectIfAuthenticated()
  public/index.php:73                                require()

Invalid SAML response

I've tried to debug it, but when logging using Firefox/Brave, unfortunately it doesn't create a debug file.

Hi @RaulGrosmam

For the debug you should manually create a directory called debug inside the phpsaml plugin directory that is writable for php. A warning message should now also popup in the config if the debug directory is detected. Also make sure the debug option is enabled in the config page.

I will dive into the logic this evening.

sharing an anonymized version the the saml dump will help the debugging efforts greatly.

Yeah, I'm aware of it, but it just create a debug file using Chrome.
image

Here's my SAML dump using SAML-Tracer on Firefox (dunno how to post it with the values, then I just removed them.)

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                Destination="http://MY_GLPI/plugins/phpsaml/front/acs.php"
                ID="ID_ebbdaeb7-bd18-4b60-89cd-a0bd81db69bf"
                InResponseTo="ONELOGIN_75373ba77c0ba67bcec18cf21d4af3d4954a94d5"
                IssueInstant="2023-06-27T15:48:59.536Z"
                Version="2.0"
                >
    <saml:Issuer>https://MY_KEYCLOAK/auth/realms/MY_REALM</saml:Issuer>
    <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        <dsig:SignedInfo>
            <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
            <dsig:Reference URI="#ID_ebbdaeb7-bd18-4b60-89cd-a0bd81db69bf">
                <dsig:Transforms>
                    <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </dsig:Transforms>
                <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <dsig:DigestValue>MY_DIGESTVALUE</dsig:DigestValue>
            </dsig:Reference>
        </dsig:SignedInfo>
        <dsig:SignatureValue>MY_SIGNATURE</dsig:SignatureValue>
        <dsig:KeyInfo>
            <dsig:X509Data>MY_CERTIFICATE</dsig:X509Certificate>
            </dsig:X509Data>
            <dsig:KeyValue>
                <dsig:RSAKeyValue>
                    <dsig:Modulus>MY_MODULUS</dsig:Modulus>
                    <dsig:Exponent>AQAB</dsig:Exponent>
                </dsig:RSAKeyValue>
            </dsig:KeyValue>
        </dsig:KeyInfo>
    </dsig:Signature>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
    </samlp:Status>
    <saml:EncryptedAssertion>
        <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
                            Type="http://www.w3.org/2001/04/xmlenc#Element"
                            >
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <xenc:EncryptedKey>
                    <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
                    <xenc:CipherData>
                        <xenc:CipherValue>MY_CIPHERVALUE</xenc:CipherValue>
                    </xenc:CipherData>
                </xenc:EncryptedKey>
            </ds:KeyInfo>
            <xenc:CipherData>
                <xenc:CipherValue>MY_CIPHERVALUE</xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedData>
    </saml:EncryptedAssertion>
</samlp:Response>

Hi @RaulGrosmam

For the debug you should manually create a directory called debug inside the phpsaml plugin directory that is writable for php. A warning message should now also popup in the config if the debug directory is detected. Also make sure the debug option is enabled in the config page.

I will dive into the logic this evening.

sharing an anonymized version the the saml dump will help the debugging efforts greatly.

Hi @RaulGrosmam,

It looks like your shared SAML response is missing the attributestatement xml block. Below you can see what a valid response should look like including the required attributes (claims). Not all listed claims (default Microsoft) are implemented by the plugin. Adding additional checks in the acs to validate all required information is present in the SAML response is one of the TODO's on my list.

<samlp:Response ID="_[ID]" 
                Version="2.0" 
                IssueInstant="2023-06-27T20:19:55.830Z" 
                Destination="https://GLPI_SERVER/glpi/plugins/phpsaml/front/acs.php" 
                InResponseTo="ONELOGIN_[ID]"
                xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://sts.windows.net/[ID]/</Issuer>
<samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
    <Assertion ID="[ID]" IssueInstant="DateTime" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
        <Issuer>https://sts.windows.net/[ID]]/</Issuer>
        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
                <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <Reference URI="[REF]">
                    <Transforms>
                        <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                        <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    </Transforms>  
                    <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                    <DigestValue>[Digest]</DigestValue>
                </Reference>
            </SignedInfo>
            <SignatureValue>[BASE64SIGN]</SignatureValue>
            <KeyInfo>
                <X509Data>
                    <X509Certificate>[BASE64CERT]</X509Certificate>
                </X509Data>
            </KeyInfo>
        </Signature>
        <Subject>
            <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">firstname.surname@domain.tld</NameID>
            <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <SubjectConfirmationData InResponseTo="ONELOGIN_[ID]" 
                                        NotOnOrAfter="DATETIME" 
                                        Recipient="https://[GLPI_SERVER]/glpi/plugins/phpsaml/front/acs.php"/>
            </SubjectConfirmation>
        </Subject>
        <Conditions NotBefore="2023-06-27T20:14:55.731Z" 
                    NotOnOrAfter="2023-06-27T21:19:55.731Z">
            <AudienceRestriction>
                <Audience>https://[GLPI_SERVER]/glpi/</Audience>
            </AudienceRestriction>
        </Conditions>
        <AttributeStatement>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
                <AttributeValue>[TENANTID]</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
                <AttributeValue>[OBJID]</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/displayname">
                <AttributeValue>Firstname Surname</AttributeValue>
            </Attribute><Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
                <AttributeValue>https://sts.windows.net/[APPID]/</AttributeValue>
            </Attribute><Attribute Name="http://schemas.microsoft.com/claims/authnmethodsreferences">
                <AttributeValue>http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password</AttributeValue>
                <AttributeValue>http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/x509</AttributeValue>
                <AttributeValue>http://schemas.microsoft.com/claims/multipleauthn</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
                <AttributeValue>Firstname</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
                <AttributeValue>Surname</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
                <AttributeValue>firstname.surname@domain.tld</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
                <AttributeValue>firstname.surname@domain.tld</AttributeValue>
            </Attribute>
        </AttributeStatement>
        <AuthnStatement AuthnInstant="2023-04-01T19:08:08.039Z" SessionIndex="_3585e278-62f0-42d6-a1bc-69f07edb1600">
            <AuthnContext>
                <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
            </AuthnContext>
        </AuthnStatement>
    </Assertion>
</samlp:Response>

Sorry, I don't know too much about it.
There's anyway to fix it by my part?

Also, here's a debug_dump when trying logging in on chrome generated by the plugin

<?php 


 Unpacked SamlResponse Methods:
Array
(
    [0] => __construct
    [1] => isValid
    [2] => getId
    [3] => getAssertionId
    [4] => getAssertionNotOnOrAfter
    [5] => checkStatus
    [6] => checkOneCondition
    [7] => checkOneAuthnStatement
    [8] => getAudiences
    [9] => getIssuers
    [10] => getNameIdData
    [11] => getNameId
    [12] => getNameIdFormat
    [13] => getNameIdNameQualifier
    [14] => getNameIdSPNameQualifier
    [15] => getSessionNotOnOrAfter
    [16] => getSessionIndex
    [17] => getAttributes
    [18] => getAttributesWithFriendlyName
    [19] => validateNumAssertions
    [20] => processSignedElements
    [21] => validateTimestamps
    [22] => validateSignedElements
    [23] => getErrorException
    [24] => getError
    [25] => getXMLDocument
)


 Unpacked SamlResponse vars:
Array
(
    [response] => <samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Destination="http://MY_GLPI/plugins/phpsaml/front/acs.php" ID="ID_0f6f064e-de0e-42bc-97ca-bb4894c34324" InResponseTo="ONELOGIN_7a4a3d7c11b2be090264e3c4458fd0593188aaca" IssueInstant="2023-06-27T20:51:14.206Z" Version="2.0">
    <saml:Issuer>https://MY_KEYCLOAK/auth/realms/MY_REALM</saml:Issuer>
    <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
    <dsig:SignedInfo>
    <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
    <dsig:Reference URI="#ID_0f6f064e-de0e-42bc-97ca-bb4894c34324">
    <dsig:Transforms>
    <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
        <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></dsig:Transforms>
            <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
            <dsig:DigestValue>4EvuS5JP8Gi4i+tZZRKvxLLA4lhLTWOqBqiQr7m8Fy8=</dsig:DigestValue>
            </dsig:Reference>
            </dsig:SignedInfo>
            <dsig:SignatureValue>MY_SIGNATURE<dsig:SignatureValue>
            <dsig:KeyInfo>
            <dsig:X509Data>
            <dsig:X509Certificate>MY_CERT</dsig:X509Certificate>
            </dsig:X509Data>
            <dsig:KeyValue>
            <dsig:RSAKeyValue>
            <dsig:Modulus>MODULUSVALUE</dsig:Modulus>
            <dsig:Exponent>AQAB</dsig:Exponent>
            </dsig:RSAKeyValue>
            </dsig:KeyValue>
            </dsig:KeyInfo>
            </dsig:Signature>
            <samlp:Status>
            <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
            </samlp:Status>
            <saml:EncryptedAssertion>
            <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <xenc:EncryptedKey>
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
            <xenc:CipherData>
            <xenc:CipherValue>CIPHERVALUE</xenc:CipherValue>
            </xenc:CipherData>
            </xenc:EncryptedKey>
            </ds:KeyInfo>
            <xenc:CipherData>
            <xenc:CipherValue>CIPHERVALUE</xenc:CipherValue>
            </xenc:CipherData>
            </xenc:EncryptedData>
            </saml:EncryptedAssertion>
            </samlp:Response>
    [document] => DOMDocument Object
        (
            [doctype] => 
            [implementation] => (object value omitted)
            [documentElement] => (object value omitted)
            [actualEncoding] => 
            [encoding] => 
            [xmlEncoding] => 
            [standalone] => 1
            [xmlStandalone] => 1
            [version] => 1.0
            [xmlVersion] => 1.0
            [strictErrorChecking] => 1
            [documentURI] => /usr/share/glpi/plugins/phpsaml/front/
            [config] => 
            [formatOutput] => 
            [validateOnParse] => 
            [resolveExternals] => 
            [preserveWhiteSpace] => 1
            [recover] => 
            [substituteEntities] => 
            [firstElementChild] => (object value omitted)
            [lastElementChild] => (object value omitted)
            [childElementCount] => 1
            [nodeName] => #document
            [nodeValue] => 
            [nodeType] => 9
            [parentNode] => 
            [childNodes] => (object value omitted)
            [firstChild] => (object value omitted)
            [lastChild] => (object value omitted)
            [previousSibling] => 
            [nextSibling] => 
            [attributes] => 
            [ownerDocument] => 
            [namespaceURI] => 
            [prefix] => 
            [localName] => 
            [baseURI] => /usr/share/glpi/plugins/phpsaml/front/
            [textContent] => SOME_INFORMATION
        )

    [decryptedDocument] => DOMDocument Object
        (
            [doctype] => 
            [implementation] => (object value omitted)
            [documentElement] => (object value omitted)
            [actualEncoding] => 
            [encoding] => 
            [xmlEncoding] => 
            [standalone] => 1
            [xmlStandalone] => 1
            [version] => 1.0
            [xmlVersion] => 1.0
            [strictErrorChecking] => 1
            [documentURI] => /usr/share/glpi/plugins/phpsaml/front/
            [config] => 
            [formatOutput] => 
            [validateOnParse] => 
            [resolveExternals] => 
            [preserveWhiteSpace] => 1
            [recover] => 
            [substituteEntities] => 
            [firstElementChild] => (object value omitted)
            [lastElementChild] => (object value omitted)
            [childElementCount] => 1
            [nodeName] => #document
            [nodeValue] => 
            [nodeType] => 9
            [parentNode] => 
            [childNodes] => (object value omitted)
            [firstChild] => (object value omitted)
            [lastChild] => (object value omitted)
            [previousSibling] => 
            [nextSibling] => 
            [attributes] => 
            [ownerDocument] => 
            [namespaceURI] => 
            [prefix] => 
            [localName] => 
            [baseURI] => /usr/share/glpi/plugins/phpsaml/front/
            [textContent] => https://MY_KEYCLOAK/auth/realms/MY_REALM + SOME INFORMATION
            https://MY_KEYCLOAK/auth/realms/MY_REALM + SOME OF THE SAME INFORMATION+raulgrosmam@mydomain.comhttp://MY_GLPI/urn:oasis:names:tc:SAML:2.0:ac:classes:unspecifiedraulgrosmam@mydomain.comRaulGrosmam Grosmam raulgrosmam@mydomain.comRaulRauloffline_accessview-profilemanage-accountmanage-account-linksuma_authorization
        )

    [encrypted] => 1
)


 POST:


 GET:
Array
(
)

Also, SAML Response on Google Chrome is the same than Firefox

The required attributes (claims) are missing in this response. See my previous post.

do you have a default profile selected?