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

feat: implement RFC 8628 #3851

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d4f1f02
chore: install fosite from branch (remove)
nsklikas Sep 25, 2024
14d2af7
fix: set utc expires_at
nsklikas Sep 25, 2024
2c0f9a0
fix: add redirect_uri to test
nsklikas Sep 25, 2024
a99fa3d
fix: add rfc8628 providers to registry
nsklikas Feb 9, 2024
0832c17
fix: update database schema
nsklikas Feb 9, 2024
905f610
fix: update oauth persister logic
nsklikas Sep 24, 2024
8f4a1ab
feat: add device authorization endpoint handler
nsklikas Feb 9, 2024
e86d044
refactor: move logic to updateSessionWithRequest method
nsklikas Feb 28, 2024
cb84dd4
fix: rename device auth endpoint handler
nsklikas Feb 28, 2024
d9c3ecc
feat: add device user verification handler
nsklikas Feb 28, 2024
365a980
fix: implement device user verification logic
nsklikas Feb 28, 2024
86e46dd
feat: update flow
nsklikas Mar 1, 2024
c4b28f8
fix: add post device auth handler
nsklikas Mar 1, 2024
1efbd3a
feat: add consent handler for accepting a user_code
nsklikas Mar 1, 2024
45abdba
chore: add post_device_done to config schema
nsklikas Mar 7, 2024
0921426
chore: add e2e tests
nsklikas Mar 11, 2024
99b5a1a
feat: token request handling for device flow
wood-push-melon Mar 23, 2024
7daab9f
chore: update config
nsklikas Mar 21, 2024
7e60cc0
fix: fix the OIDC token and refresh token issue for device flow
wood-push-melon Apr 11, 2024
413f7c1
fix: update OpenID Connect session after user consent
wood-push-melon Apr 12, 2024
a140169
fix: add GetDeviceCodeSessionByRequestID method
nsklikas Apr 15, 2024
ff9933c
fix: return client_id to post_device page
nsklikas Apr 15, 2024
eec977c
fix: update existing device session
nsklikas Apr 15, 2024
87b2cef
fix: update tests
nsklikas Apr 15, 2024
b9e587f
fix: add device auth endpoint in discovery metadata
nsklikas Apr 23, 2024
5c56722
fix: make device grant lifetimes configurable
nsklikas Apr 25, 2024
8dfdaea
test: update sql fixtures
nsklikas Apr 29, 2024
159c178
fix: perform device flow from CLI
nsklikas May 22, 2024
ae1afc2
fix: wrap db calls in transaction
nsklikas Jul 30, 2024
872bebd
chore: fix license
nsklikas Sep 25, 2024
9f2dec8
chore: update sdk
nsklikas Sep 24, 2024
968a4a1
fix: duplicate user_code update
nsklikas Sep 26, 2024
a6c8cee
refactor: merge user and device code tables
nsklikas Nov 15, 2024
ccafea3
fix: create openid session when log in succeeds
nsklikas Nov 18, 2024
ced8b62
refactor: update device session persistence logic
nsklikas Nov 15, 2024
469c5e1
fix: update oauth persister logic
nsklikas Dec 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .schema/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,11 @@
"description": "Sets the session cookie name. Use with care!",
"type": "object",
"properties": {
"device_csrf": {
Copy link
Member

Choose a reason for hiding this comment

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

There are several new config keys. Please add them here

"type": "string",
"title": "CSRF Cookie Name",
"default": "ory_hydra_device_csrf"
},
"login_csrf": {
"type": "string",
"title": "CSRF Cookie Name",
Expand Down Expand Up @@ -645,6 +650,14 @@
"examples": [
"https://example.org/my-custom-userinfo-endpoint"
]
},
"device_authorization_url": {
"type": "string",
"description": "A URL of the device authorization endpoint to be advertised at the OpenID Connect Discovery endpoint /.well-known/openid-configuration. Defaults to Ory Hydra's device authorizatoin endpoint at /oauth2/device/auth. Set this value if you want to handle this endpoint yourself.",
"format": "uri-reference",
"examples": [
"https://example.org/oauth2/device/auth"
]
}
}
}
Expand Down Expand Up @@ -803,6 +816,24 @@
"/ui/logout"
]
},
"device_verification": {
"type": "string",
"description": "Sets the device user code verification endpoint. Defaults to an internal fallback URL showing an error.",
"format": "uri-reference",
"examples": [
"https://my-logout.app/device_verification",
"/ui/device_verification"
]
},
"post_device_done": {
"type": "string",
"description": "Sets the post device authentication endpoint. Defaults to an internal fallback URL showing an error.",
"format": "uri-reference",
"examples": [
"https://my-logout.app/device_done",
"/ui/device_done"
]
},
"error": {
"type": "string",
"description": "Sets the error endpoint. The error ui will be shown when an OAuth2 error occurs that which can not be sent back to the client. Defaults to an internal fallback URL showing an error.",
Expand Down Expand Up @@ -947,6 +978,15 @@
"$ref": "#/definitions/duration"
}
]
},
"device_user_code": {
"description": "Configures how long device and user codes are valid.",
"default": "15m",
"allOf": [
{
"$ref": "#/definitions/duration"
}
]
}
}
},
Expand Down Expand Up @@ -1064,6 +1104,17 @@
}
}
},
"device_authorization": {
"token_polling_interval": {
"description": "Sets the starting token polling interval.",
"default": "5s",
"allOf": [
{
"$ref": "#/definitions/duration"
}
]
}
},
"grant": {
"type": "object",
"additionalProperties": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
},
"status": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
},
"status": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
"jwt_bearer_grant_access_token_lifespan": "37h0m0s",
"refresh_token_grant_id_token_lifespan": "40h0m0s",
"refresh_token_grant_access_token_lifespan": "41h0m0s",
"refresh_token_grant_refresh_token_lifespan": "42h0m0s"
"refresh_token_grant_refresh_token_lifespan": "42h0m0s",
"device_authorization_grant_id_token_lifespan": "45h0m0s",
"device_authorization_grant_access_token_lifespan": "46h0m0s",
"device_authorization_grant_refresh_token_lifespan": "47h0m0s"
},
"status": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
},
"status": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
},
"status": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
"refresh_token_grant_refresh_token_lifespan": null,
"device_authorization_grant_id_token_lifespan": null,
"device_authorization_grant_access_token_lifespan": null,
"device_authorization_grant_refresh_token_lifespan": null
}
24 changes: 24 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type Client struct {
// - OpenID Connect Implicit Grant (deprecated!): `implicit`
// - Refresh Token Grant: `refresh_token`
// - OAuth 2.0 Token Exchange: `urn:ietf:params:oauth:grant-type:jwt-bearer`
// - OAuth 2.0 Device Code Grant: `urn:ietf:params:oauth:grant-type:device_code`
GrantTypes sqlxx.StringSliceJSONFormat `json:"grant_types" db:"grant_types"`

// OAuth 2.0 Client Response Types
Expand Down Expand Up @@ -379,6 +380,21 @@ type Lifespans struct {
//
// The lifespan of a refresh token issued by the OAuth2 2.0 Refresh Token Grant for this OAuth 2.0 Client.
RefreshTokenGrantRefreshTokenLifespan x.NullDuration `json:"refresh_token_grant_refresh_token_lifespan,omitempty" db:"refresh_token_grant_refresh_token_lifespan"`

// OAuth2 2.0 Device Authorization Grant ID Token Lifespan
//
// The lifespan of an ID token issued by the OAuth2 2.0 Device Authorization Grant for this OAuth 2.0 Client.
DeviceAuthorizationGrantIDTokenLifespan x.NullDuration `json:"device_authorization_grant_id_token_lifespan,omitempty" db:"device_authorization_grant_id_token_lifespan"`
Copy link
Member

Choose a reason for hiding this comment

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

Note to self: this will increase the challenge size


// OAuth2 2.0 Device Authorization Grant Access Token Lifespan
//
// The lifespan of an access token issued by the OAuth2 2.0 Device Authorization Grant for this OAuth 2.0 Client.
DeviceAuthorizationGrantAccessTokenLifespan x.NullDuration `json:"device_authorization_grant_access_token_lifespan,omitempty" db:"device_authorization_grant_access_token_lifespan"`

// OAuth2 2.0 Device Authorization Grant Device Authorization Lifespan
//
// The lifespan of a Device Authorization issued by the OAuth2 2.0 Device Authorization Grant for this OAuth 2.0 Client.
DeviceAuthorizationGrantRefreshTokenLifespan x.NullDuration `json:"device_authorization_grant_refresh_token_lifespan,omitempty" db:"device_authorization_grant_refresh_token_lifespan"`
}

func (Client) TableName() string {
Expand Down Expand Up @@ -549,6 +565,14 @@ func (c *Client) GetEffectiveLifespan(gt fosite.GrantType, tt fosite.TokenType,
} else if tt == fosite.RefreshToken && c.RefreshTokenGrantRefreshTokenLifespan.Valid {
cl = &c.RefreshTokenGrantRefreshTokenLifespan.Duration
}
} else if gt == fosite.GrantTypeDeviceCode {
if tt == fosite.AccessToken && c.DeviceAuthorizationGrantAccessTokenLifespan.Valid {
cl = &c.DeviceAuthorizationGrantAccessTokenLifespan.Duration
} else if tt == fosite.IDToken && c.DeviceAuthorizationGrantIDTokenLifespan.Valid {
cl = &c.DeviceAuthorizationGrantIDTokenLifespan.Duration
} else if tt == fosite.RefreshToken && c.DeviceAuthorizationGrantRefreshTokenLifespan.Valid {
cl = &c.DeviceAuthorizationGrantRefreshTokenLifespan.Duration
}
}

if cl == nil {
Expand Down
2 changes: 2 additions & 0 deletions client/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ory/fosite"
foauth2 "github.com/ory/fosite/handler/oauth2"
"github.com/ory/fosite/handler/rfc8628"
enigma "github.com/ory/fosite/token/hmac"
"github.com/ory/hydra/v2/jwk"
"github.com/ory/hydra/v2/x"
Expand All @@ -25,5 +26,6 @@ type Registry interface {
OpenIDJWTStrategy() jwk.JWTSigner
OAuth2HMACStrategy() foauth2.CoreStrategy
OAuth2EnigmaStrategy() *enigma.HMACStrategy
RFC8628HMACStrategy() rfc8628.RFC8628CodeStrategy
config.Provider
}
Loading
Loading