Closed leighmcculloch closed 4 years ago
Thanks Leigh,
This should do the trick:
def _generate_jwt(request, envelope_xdr):
"""
Generates the JSON web token from the challenge transaction XDR.
See: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md#token
"""
issued_at = time.time()
transaction_envelope = TransactionEnvelope.from_xdr(
envelope_xdr,
network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE
)
transaction = transaction_envelope.transaction
hash_hex = binascii.hexlify(transaction_envelope.hash()).decode()
jwt_dict = {
"iss": request.build_absolute_uri("/auth"),
"sub": transaction.source.public_key,
"iat": issued_at,
"exp": issued_at + 24 * 60 * 60,
"jti": hash_hex,
}
encoded_jwt = jwt.encode(jwt_dict, settings.SERVER_JWT_KEY, algorithm="HS256")
return encoded_jwt.decode("ascii")
We'll release this adjustment in v0.9.3
Turns out the transaction's source is the anchor's account since its a challenge generated by the server. So instead of assigning sub
to transaction.source.public_key
, we'll use transaction.operations[0].source
as defined in SEP-10:
transaction
: an XDR-encoded Stellar transaction with the following:
- source account set to server's signing account
- invalid sequence number (set to 0) so the transaction cannot be run on the Stellar network
- time bounds:
{min: now(), max: now() + 300 }
(we recommend expiration of 5 minutes to give user time to sign transaction)- operations:
manage_data(source: client_account, key: '<anchor name> auth', value: random_nonce())
- The value of key is not important, but can be the name of the anchor followed by
auth
. It can be at most 64 bytes.- The value must be 64 bytes long. It contains a 48 byte cryptographic-quality random string encoded using base64 (for a total of 64 bytes after encoding).
- signature by the web service signing account
...
- use operations's source account to determine the authenticating client and perform any additional service-specific validations.
What version are you using?
v0.9.2
What did you do?
I haven't used polaris yet but I took a look at the SEP-10 implementation here: https://github.com/stellar/django-polaris/blob/1da3dd3ffd2e59dfbc19e27aceaeb097b5ad94f3/polaris/polaris/sep10auth/views.py#L99-L117
What did you expect to see?
I expected to see the address/public-key of the Client's Stellar account set as the
sub
field of the JWT. The Client's address is the source account of the challenge transaction's first manage data operation.According to SEP-10's definition of what is in a token the
sub
field should contain:The
authenticating
Stellar account is the client.What did you see instead?
The address/public-key of the distribution Stellar account set as the
sub
field of the JWT.