Single Sign On - SSO
Implementação necessaria para realizar o SSO
- O primeiro passo para começar a implementação do fluxo de SSO é a disponibilização de um endpoint com uma chave pública de assinatura. Visite Jwks pra entender mais e sobre como você obtém essa chave.
- Criar um Id token do usuario logado, assinado com a chave privada referente à chave pública disponibilizada no endpoint de Jwks. Segue exemplo de payload e implementação programática em C#:
{
"sub": "{cpf do usuario logado}",
"jti": "e2e3b202-19e9-46dc-b061-c5f22eb34194",
"name": "NOME DO USUARIO",
"email": "[email protected]",
"phone_number": "{telefone do usuario}", // ex:5511000000000
"exp": 1706299657,
"iss": "{base path do endpoint jwks}", //ex: https://id.sandbox.btgpactual.com/.well-known/jwks
"aud": "btg:empresas:companies:{cnpj}"
}
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, ""),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim("name", ""),
new Claim("email", ""),
new Claim("phone_number", ""),
};
var rsaParameters = rsaKeyForSigning.ExportParameters(true);
var rsaSecurityKey = new RsaSecurityKey(rsaParameters);
var signingCredentials = new SigningCredentials(rsaSecurityKey, SecurityAlgorithms.RsaSha256);
var tokenOptions = new JwtSecurityToken(
issuer: iss,
audience: "btg:empresas:companies:{cnpj_onboarding}",
claims: claims,
expires: DateTime.Now.AddMinutes(2),
signingCredentials: signingCredentials
);
var tokenHandler = new JwtSecurityTokenHandler();
var idToken = tokenHandler.WriteToken(tokenOptions);
- Após assinar o id token, você deverá obter no endpoint de jwks do BTG Pactual Empresas a chave pública de criptografia
using var httpClient = new HttpClient();
var btgIdJwksEndpoint = "https://id.btgpactual.com/.well-known/jwks";
var jwksResponse = httpClient.GetStringAsync(btgIdJwksEndpoint).Result;
var jwksData = JObject.Parse(jwksResponse);
var encryptionKeyData = jwksData["keys"].FirstOrDefault(k => k["use"].ToString() == "enc");
string e = encryptionKeyData["e"].ToString();
string n = encryptionKeyData["n"].ToString();
Jwk rsaEncryptionKey = new Jwk(e, n);
- Com a chave pública de criptografia, você agora deve utilizá-la para gerar um JWE, que nada mais é do que o JWT referente ao id token encriptado.
var headers = new Dictionary<string, object>
{
{ "kid", encryptionKeyData["kid"].ToString() }
};
var recipients = new JweRecipient[]
{
new JweRecipient(JweAlgorithm.RSA1_5, rsaEncryptionKey, headers)
};
string encryptedJweIdToken = JWE.Encrypt(idToken, recipients, JweEncryption.A256GCM, mode: SerializationMode.Compact);
- Com o JWE em mãos você deve criar um RAR(rich authorization request) conforme abaixo:
{
"type": "btg:empresas:apps:b2b:onboarding",
"idp": "{parceiro_idp}", //idp do parceiro cadastrado no BtgId
"principal": "{parceiro_client_id}",
"resource": "btg:empresas:companies:{cnpj_onboarding}",
"privileges": "btg:empresas:gatekeeper:apps:onboarding-enrichment"
}
var authorizationDetails = WebUtility.UrlEncode(JsonConvert.SerializeObject(new[]
{
new {
type = "btg:empresas:apps:b2b:onboarding",
idp = "{parceiro_idp}", //idp do parceiro cadastrado no BtgId
principal = "{parceiro_client_id}",
resource = "btg:empresas:companies:{cnpj_onboarding}",
privileges = new string[] { "btg:empresas:gatekeeper:apps:onboarding-enrichment" }
}
}));
- Após realizar o RAR, deve-se realizar um redirecionamento para o seguinte endereço preenchendo os campos com os dados obtidos ao longo do fluxo:
https://app.empresas.btgpactual.com/conta-pj-btg?idp_hint={parceiro_idp}&acr_values={parceiro_idp}:sso&id_token_hint={encryptedJweIdToken}&authorization_details={authorizationDetails}&redirect=L2NhZGFzdHJvL3BhcmNlaXJv
Onde:
idp_hint
: Campo referente ao "idp" presente no RAR.acr_values
: Campo referente ao "idp" presente no RAR.id_token_hint
: Campo referente ao JWE encriptado.authorization_details
: Campo referente à varauthorizationDetails
redirect
: Campo fixo com valorL2NhZGFzdHJvL3BhcmNlaXJv
Updated 7 months ago