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 #3912

Open
wants to merge 37 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7656cb2
chore: install fosite from branch (remove)
nsklikas Sep 25, 2024
13a4954
fix: set utc expires_at
nsklikas Sep 25, 2024
b608351
fix: add redirect_uri to test
nsklikas Sep 25, 2024
312edd5
fix: add rfc8628 providers to registry
nsklikas Feb 9, 2024
2225f0f
fix: update database schema
nsklikas Feb 9, 2024
74764ec
fix: update oauth persister logic
nsklikas Sep 24, 2024
36373bf
feat: add device authorization endpoint handler
nsklikas Feb 9, 2024
0b41422
refactor: move logic to updateSessionWithRequest method
nsklikas Feb 28, 2024
85d735d
fix: rename device auth endpoint handler
nsklikas Feb 28, 2024
82b5bb4
feat: add device user verification handler
nsklikas Feb 28, 2024
cf6ab7e
fix: implement device user verification logic
nsklikas Feb 28, 2024
b4fbb66
feat: update flow
nsklikas Mar 1, 2024
d134f50
fix: add post device auth handler
nsklikas Mar 1, 2024
75fa60e
feat: add consent handler for accepting a user_code
nsklikas Mar 1, 2024
a2bd82a
chore: add post_device_done to config schema
nsklikas Mar 7, 2024
1058ddb
chore: add e2e tests
nsklikas Mar 11, 2024
f7c1eb7
feat: token request handling for device flow
wood-push-melon Mar 23, 2024
fe21aaf
chore: update config
nsklikas Mar 21, 2024
fb376d5
fix: fix the OIDC token and refresh token issue for device flow
wood-push-melon Apr 11, 2024
6702006
fix: update OpenID Connect session after user consent
wood-push-melon Apr 12, 2024
9c9db7b
fix: add GetDeviceCodeSessionByRequestID method
nsklikas Apr 15, 2024
f69ffc0
fix: return client_id to post_device page
nsklikas Apr 15, 2024
d9a7d8d
fix: update existing device session
nsklikas Apr 15, 2024
8d38a4f
fix: update tests
nsklikas Apr 15, 2024
5232b1e
fix: add device auth endpoint in discovery metadata
nsklikas Apr 23, 2024
92c531f
fix: make device grant lifetimes configurable
nsklikas Apr 25, 2024
57828f2
test: update sql fixtures
nsklikas Apr 29, 2024
b79e92b
fix: perform device flow from CLI
nsklikas May 22, 2024
bdb05d1
fix: wrap db calls in transaction
nsklikas Jul 30, 2024
ffad0ba
chore: fix license
nsklikas Sep 25, 2024
51d6fa1
chore: update sdk
nsklikas Sep 24, 2024
ac71724
fix: duplicate user_code update
nsklikas Sep 26, 2024
ad43575
refactor: merge user and device code tables
nsklikas Nov 15, 2024
d80b044
fix: create openid session when log in succeeds
nsklikas Nov 18, 2024
f1bb19a
refactor: update device session persistence logic
nsklikas Nov 15, 2024
bbd3db5
fix: update oauth persister logic
nsklikas Dec 10, 2024
8790af4
fix: handle user_code collisions
nsklikas Jan 8, 2025
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": {
"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"`

// 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