Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Client Assertion authentication on authentication client #260

Merged
merged 8 commits into from
Aug 11, 2023

Conversation

ewanharris
Copy link
Contributor

🔧 Changes

Introduces support for using Client Assertion to the authentication client, this is for use when the Authentication Method is set to Private Ket JWT. This is supported using the WithClientAssertion option that can be passed instead of the existing WithClientSecret

jwtPrivateKey := `-----BEGIN PRIVATE KEY-----
.......
-----END PRIVATE KEY-----`

api, err := New(
	context.Background(),
	domain,
	WithClientID(clientID),
	WithClientAssertion(jwtPrivateKey, "RS256"),
)

if err != nil {
	log.Fatal(err)
}

tokenSet, err := api.OAuth.LoginWithClientCredentials(context.Background(), oauth.LoginWithClientCredentialsRequest{}, oauth.IDTokenValidationOptions{})

if err != nil {
	log.Fatal(err)
}

log.Print(tokenSet)

📚 References

🔬 Testing

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

@ewanharris ewanharris requested a review from a team as a code owner August 8, 2023 13:09
@ewanharris ewanharris force-pushed the feat/SDK-4419-private-key-jwt branch from af0e295 to cefca23 Compare August 8, 2023 13:11
break
}

if required && (body.Get("client_secret") == "" && body.Get("client_assertion") == "") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the && in (body.Get("client_secret") == "" && body.Get("client_assertion") == "") be a ||?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to error here if both values are empty as the they can be used independently of each other, so if client_secret is empty but client_assertion is not then we can continue

JwtID(uuid.New().String()).
Issuer(clientID).
Audience([]string{domain}).
Expiration(time.Now().Add(2 * time.Minute)).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity, where does this 2 minute exp come from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was aligning with the value set by the node-auth0 v4 beta here, I think there's not really a specific reason for picking 2 minutes, the only requirement is that exp must be a value no more than 5 minutes after the iat

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense for this exp value to be configurable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we currently support configuring this on any other SDK and I haven't seen any request to do so yet, so I'd maybe defer to adding if we get a request

@codecov-commenter
Copy link

codecov-commenter commented Aug 9, 2023

Codecov Report

Patch coverage: 76.23% and project coverage change: -0.24% ⚠️

Comparison is base (4c4f9dc) 94.89% compared to head (84b9185) 94.66%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #260      +/-   ##
==========================================
- Coverage   94.89%   94.66%   -0.24%     
==========================================
  Files          46       46              
  Lines        8441     8523      +82     
==========================================
+ Hits         8010     8068      +58     
- Misses        337      353      +16     
- Partials       94      102       +8     
Files Changed Coverage Δ
authentication/authentication.go 89.53% <ø> (ø)
authentication/passwordless.go 81.48% <53.12%> (-18.52%) ⬇️
authentication/oauth.go 89.77% <85.93%> (-2.79%) ⬇️
authentication/authentication_option.go 93.61% <100.00%> (+0.75%) ⬆️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ewanharris ewanharris requested a review from Widcket August 9, 2023 10:48
Widcket
Widcket previously approved these changes Aug 10, 2023
sergiught
sergiught previously approved these changes Aug 10, 2023
Copy link
Contributor

@sergiught sergiught left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just very small suggestions, overall things look good 👍🏻

@@ -155,6 +158,7 @@ func New(ctx context.Context, domain string, options ...Option) (*Authentication
auth0ClientInfo: client.DefaultAuth0ClientInfo,
idTokenSigningAlg: "RS256",
retryStrategy: client.DefaultRetryOptions,
domain: domain + "/",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use url.JoinPath here instead? If the domain already contains "/"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's a good point, on reflection it's probably a bit wasteful to have a separate domain here (just for the added /) when we already have url

@@ -70,7 +79,11 @@ func (p *Passwordless) SendSMS(ctx context.Context, params passwordless.SendSMSR
//
// See: https://auth0.com/docs/api/authentication?http#authenticate-user
func (p *Passwordless) LoginWithSMS(ctx context.Context, params passwordless.LoginWithSMSRequest, validationOptions oauth.IDTokenValidationOptions, opts ...RequestOption) (t *oauth.TokenSet, err error) {
p.addClientAuthentication(&params.ClientAuthentication)
err = p.addClientAuthentication(&params.ClientAuthentication)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

authentication/passwordless_test.go Outdated Show resolved Hide resolved
authentication/passwordless_test.go Outdated Show resolved Hide resolved
@ewanharris ewanharris dismissed stale reviews from sergiught and Widcket via cc62c96 August 11, 2023 09:27
@ewanharris ewanharris merged commit a98b898 into main Aug 11, 2023
4 checks passed
@ewanharris ewanharris deleted the feat/SDK-4419-private-key-jwt branch August 11, 2023 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants