External SSO provider but discourse logs say None has already expired (please help!)

We are using Firebase as our external SSO provider. We have followed the discourse instructions on this.

We get an error in the logs as follows:

Verbose SSO log: Started SSO Process add_groups: admin: moderator: avatar_force_update: avatar_url: bio: card_background_url: email: external_id: groups: locale: locale_force_update: logo

Verbose SSO log: Nonce has already expired add_groups: admin: moderator: avatar_force_update: avatar_url: bio: card_background_url: email: [real email]: external_id: [external id]

We also see in the discourse logs:

Verbose SSO log: Started SSO process

add_groups:
admin:
moderator:
avatar_force_update:
avatar_url:
bio:
card_background_url:
email:
external_id:
groups:
locale:
locale_force_update:
logout:
name:
nonce: 773cb9d08db7007c9fb833e6c5e3a701
profile_background_url:
remove_groups:
require_activation:
return_sso_url: https://discouse-site/session/sso_login
suppress_welcome_message:
title:
username:
website:
location:

AND

Verbose SSO log: Nonce has already expired

add_groups:
admin:
moderator:
avatar_force_update:
avatar_url:
bio:
card_background_url:
email: [real email]
external_id: Be06ze0v0YO7I8SArWRoUVsxJ1k1
groups:
locale:
locale_force_update:
logout:
name: [real email]
nonce: Ym05dVkyVTlOV0kwTTJVeU1UTTVNamN6TnpNd01UbG1aVEJtWkRjMFlqTmtOV1U1TmpJbWNtVjBkWEp1WDNOemIxOTFjbXc5YUhSMGNITWxNMEVsTWtZbE1rWmpiMjF0ZFc1cGRIa3VZbTl2Wnk1aGNIQWxNa1p6WlhOemFXOXVKVEpHYzNOdlgyeHZaMmx1
profile_background_url:
remove_groups:
require_activation:
return_sso_url: https://discouse-site/session/sso_login
suppress_welcome_message:
title:
username: [real email]
website:
location:

Any help from the discourse team would be appreciated as we are currently unable to use the site.

James

I’m not expert in such, but my guess is to check whether you’re clock is correct.

Thanks for the suggestion but the clock doesn’t appear to be the issue. The discourse server and server from which the nonce is generated is on the same time.

1 Like

I am sharing the way that we generate the return url, to hopefully shed some more light on this problem:

   public String generateSSORedirectURL(String nonce, String email, String uid) {

    //generate the return payload
    HashMap<String, String> params = new HashMap<String, String>();
    params.put("nonce", nonce);
    params.put("external_id",uid);
    params.put("email",email);
    params.put("username",email);
    params.put("require_activation","false");
    params.put("name",email);
    params.put("return_sso_url","https://discourse-site/session/sso_login");
    log.info("params {}", params);

    //prepare the return payload
    String encodedParams = params.keySet().stream()
        .map(key -> key + "=" + encodeValue(params.get(key)))
        .collect(Collectors.joining("&"));
    log.info("encoded parameters {}", encodedParams);

    String returnPayload = Base64.getEncoder().encodeToString(encodedParams.getBytes());
    log.info("return Payload {}", returnPayload);

    //calculate the hmacSha256 signature for the payload
    byte[] hmacSha256 = calcHmacSha256(ssoSecret.getBytes(), returnPayload.getBytes());
    log.info("hmacSha256 sig {}", hmacSha256);
    
    String hmacSha265Hex = String.format("%x", new BigInteger(1, hmacSha256));
    log.info("hmacSha256, sig in Hex {}", String.format("%x", new BigInteger(1, hmacSha256)));

    HashMap<String, String> params2 = new HashMap<String, String>();
    params2.put("sig", hmacSha265Hex);
    params2.put("sso", returnPayload);
    log.info("params2 {}", params);

    String encodedParams2 = params2.keySet().stream()
        .map(key -> key + "=" + encodeValue(params2.get(key)))
        .collect(Collectors.joining("&"));
    log.info("encoded parameters {}", encodedParams2);

    //build and return the query string
    String queryString = forumUrl + "session/sso_login?" + encodedParams2;
    log.info("queryString {}", queryString);

    return queryString;
}