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

Switch to use sessionType=refresh_token #4975

Merged
merged 20 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e0256ef
Update @authgear/web to latest version
louischan-oursky Jan 10, 2025
6ef0119
Use accounts.portal.localhost:3100 to access accounts
louischan-oursky Jan 9, 2025
18ebe64
Update the config of portal application to be compatible with refresh…
louischan-oursky Jan 9, 2025
4f04372
Make network calls compatible with refresh token
louischan-oursky Jan 9, 2025
79190dc
Move logout to Authenticated.tsx
louischan-oursky Jan 9, 2025
11afbdd
Move configureAuthgear to Authenticated.tsx
louischan-oursky Jan 10, 2025
09f5d4f
Introduce AuthenticatedContext that support both sessionType
louischan-oursky Jan 10, 2025
5cb5e56
Only mount SessionInfoMiddleware in routes that need session
louischan-oursky Jan 10, 2025
7ca56e9
Add envvar AUTHGEAR_WEB_SDK_SESSION_TYPE
louischan-oursky Jan 10, 2025
190e1d4
Use sessionType from system config
louischan-oursky Jan 10, 2025
5892e4b
Support AUTHGEAR_WEB_SDK_SESSION_TYPE in SessionInfoMiddleware
louischan-oursky Jan 10, 2025
c2de9e4
Re-organize id token and at+jwt generation code
louischan-oursky Jan 13, 2025
80e0e34
Move sid handling to oauth
louischan-oursky Jan 13, 2025
10da048
Make IssueAccessGrant and EncodeAccessToken take options
louischan-oursky Jan 13, 2025
022960e
Include auth_time and amr in at+jwt
louischan-oursky Jan 13, 2025
655cdb9
Read amr in at+jwt
louischan-oursky Jan 13, 2025
a8dafda
Read auth_time in at+jwt
louischan-oursky Jan 13, 2025
2882363
Split 8000 and 8010 into 8000,8001,8010,8011
louischan-oursky Jan 13, 2025
5878871
Upgrade @authgear/web to 2.12.0
louischan-oursky Jan 13, 2025
8143b95
Change console.log to console.info and use substitution string
louischan-oursky Jan 14, 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
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ TRUST_PROXY=true
AUTHGEAR_APP_ID=accounts
AUTHGEAR_CLIENT_ID=portal
AUTHGEAR_ENDPOINT=http://accounts.portal.localhost:3100
AUTHGEAR_WEB_SDK_SESSION_TYPE=refresh_token

# Use a pool size of 2 to make potential deadlock visible.
# 1 connection is dedicated for LISTEN config source change.
Expand Down
3 changes: 2 additions & 1 deletion .vettedpositions
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@
/pkg/lib/session/test/context.go:85:35: requestcontext
/pkg/lib/workflow/intl_middleware.go:16:41: requestcontext
/pkg/portal/csp_middleware.go:16:39: requestcontext
/pkg/portal/session/middleware_session_info.go:19:37: requestcontext
/pkg/portal/session/middleware_session_info.go:54:9: requestcontext
/pkg/portal/session/middleware_session_info.go:175:36: requestcontext
/pkg/portal/session/middleware_session_required.go:12:38: requestcontext
/pkg/portal/transport/admin_api_handler.go:54:45: requestcontext
/pkg/portal/transport/admin_api_handler.go:61:44: requestcontext
Expand Down
57 changes: 42 additions & 15 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
- [Contributing guide](#contributing-guide)
* [Contributing guide](#contributing-guide)
* [Install dependencies](#install-dependencies)
+ [Install dependencies with asdf and homebrew](#install-dependencies-with-asdf-and-homebrew)
+ [Install dependencies with Nix Flakes](#install-dependencies-with-nix-flakes)
* [Install dependencies with asdf and homebrew](#install-dependencies-with-asdf-and-homebrew)
* [Install dependencies with Nix Flakes](#install-dependencies-with-nix-flakes)
* [Set up environment](#set-up-environment)
* [Set up the database](#set-up-the-database)
* [Set up MinIO](#setup-minio)
* [Set up MinIO](#set-up-minio)
* [Run](#run)
* [Create an account for yourselves and grant you access to the portal](#create-an-account-for-yourselves-and-grant-you-access-to-the-portal)
* [Known issues](#known-issues)
+ [Known issues on portal](#known-issues-on-portal)
* [Known issues on portal](#known-issues-on-portal)
* [Comment tags](#comment-tags)
* [Common tasks](#common-tasks)
+ [How to create a new database migration?](#how-to-create-a-new-database-migration)
+ [Set up HTTPS to develop some specific features](#set-up-https-to-develop-some-specific-features)
+ [Create release tag for a deployment](#create-release-tag-for-a-deployment)
+ [Keep dependencies up-to-date](#keep-dependencies-up-to-date)
+ [Generate Translation](#generate-translation)
* [How to create a new database migration?](#how-to-create-a-new-database-migration)
* [Set up HTTPS to develop some specific features](#set-up-https-to-develop-some-specific-features)
* [Create release tag for a deployment](#create-release-tag-for-a-deployment)
* [Keep dependencies up\-to\-date](#keep-dependencies-up-to-date)
* [Generate translation](#generate-translation)
* [Set up LDAP for local development](#set-up-ldap-for-local-development)
* [Create a LDAP user](#create-a-ldap-user)
* [Configure Authgear](#configure-authgear)
* [Start with the profile ldap](#start-with-the-profile-ldap)

# Contributing guide

Expand Down Expand Up @@ -159,11 +163,17 @@ use flake
client_id: portal
# Note that the trailing slash is very important here
# URIs are compared byte by byte.
refresh_token_lifetime_seconds: 86400
refresh_token_idle_timeout_enabled: true
refresh_token_idle_timeout_seconds: 1800
issue_jwt_access_token: true
access_token_lifetime_seconds: 900
redirect_uris:
# This redirect URI is used by the portal development server.
# See nginx.conf for the difference between 8000, 8001, 8010, and 8011
- "http://portal.localhost:8000/oauth-redirect"
# This redirect URI is used by the portal production build.
- "http://portal.localhost:8001/oauth-redirect"
- "http://portal.localhost:8010/oauth-redirect"
- "http://portal.localhost:8011/oauth-redirect"
# This redirect URI is used by the iOS and Android demo app.
- "com.authgear.example://host/path"
# This redirect URI is used by the React Native demo app.
Expand All @@ -177,9 +187,6 @@ use flake
- "http://portal.localhost:8000/"
# This redirect URI is used by the portal production build.
- "http://portal.localhost:8010/"
grant_types: []
response_types:
- none
```

3. Set up `.localhost`
Expand Down Expand Up @@ -212,6 +219,12 @@ use flake
go run ./cmd/authgear search database migrate up
```

3. Add domain

```
go run ./cmd/portal internal domain create-custom accounts --apex-domain="accounts.portal.localhost" --domain="accounts.portal.localhost"
```

## Set up MinIO

```sh
Expand Down Expand Up @@ -485,3 +498,17 @@ To start them, you need to add `--profile ldap` to `docker compose up -d`, like
```
docker compose --profile ldap up -d
```

## Switching between sessionType=refresh_token and sessionType=cookie

The default configuration

- Accessing the portal at port 8000 or 8010
- AUTHGEAR_WEB_SDK_SESSION_TYPE in .env.example

assumes sessionType=refresh_token.

In case you need to switch to sessionType=cookie, you

- Use `AUTHGEAR_WEB_SDK_SESSION_TYPE=cookie` in your .env
- Access the portal at port 8001 or 8011
2 changes: 2 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ services:
- ./tls-cert.pem:/etc/nginx/tls-cert.pem
ports:
- "8000:8000"
- "8001:8001"
- "8010:8010"
- "8011:8011"
- "3100:3100"
- "443:443"

Expand Down
97 changes: 95 additions & 2 deletions nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,12 @@ http {
proxy_pass http://host.docker.internal:3001/resolve;
proxy_pass_request_body off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host "accounts.localhost";
proxy_set_header X-Forwarded-Host "accounts.portal.localhost:3100";
proxy_set_header Content-Length "";
}
}

# vite dev server, sessionType=refresh_token
server {
server_name _;
listen 8000;
Expand All @@ -91,6 +92,98 @@ http {
proxy_set_header Connection $connection_upgrade;
}

location ~ ^/api {
proxy_pass http://host.docker.internal:3003;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}

# vite dev server, sessionType=cookie
server {
server_name _;
listen 8001;

location / {
proxy_pass http://host.docker.internal:1234;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}

location ~ ^/api {
proxy_pass http://host.docker.internal:3003;
proxy_set_header Host $http_host;

auth_request /_auth;

auth_request_set $x_authgear_session_valid $upstream_http_x_authgear_session_valid;
auth_request_set $x_authgear_user_id $upstream_http_x_authgear_user_id;
auth_request_set $x_authgear_user_anonymous $upstream_http_x_authgear_user_anonymous;
auth_request_set $x_authgear_user_verified $upstream_http_x_authgear_user_verified;
auth_request_set $x_authgear_session_acr $upstream_http_x_authgear_session_acr;
auth_request_set $x_authgear_session_amr $upstream_http_x_authgear_session_amr;
auth_request_set $x_authgear_session_authenticated_at $upstream_http_x_authgear_session_authenticated_at;
auth_request_set $x_authgear_user_can_reauthenticate $upstream_http_x_authgear_user_can_reauthenticate;

proxy_set_header x-authgear-session-valid $x_authgear_session_valid;
proxy_set_header x-authgear-user-id $x_authgear_user_id;
proxy_set_header x-authgear-user-anonymous $x_authgear_user_anonymous;
proxy_set_header x-authgear-user-verified $x_authgear_user_verified;
proxy_set_header x-authgear-session-acr $x_authgear_session_acr;
proxy_set_header x-authgear-session-amr $x_authgear_session_amr;
proxy_set_header x-authgear-session-authenticated-at $x_authgear_session_authenticated_at;
proxy_set_header x-authgear-user-can-reauthenticate $x_authgear_user_can_reauthenticate;
}

location = /_auth {
internal;
proxy_pass http://host.docker.internal:3001/resolve;
proxy_pass_request_body off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host "accounts.portal.localhost:3100";
proxy_set_header Content-Length "";
}
}

# portal production build, sessionType=refresh_token
server {
server_name _;
listen 8010;

location / {
proxy_pass http://host.docker.internal:3003;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}

location ~ ^/api {
proxy_pass http://host.docker.internal:3003;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}

# portal production build, sessionType=cookie
server {
server_name _;
listen 8011;

location / {
proxy_pass http://host.docker.internal:3003;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}

location ~ ^/api {
proxy_pass http://host.docker.internal:3003;
proxy_set_header Host $http_host;
Expand Down Expand Up @@ -121,7 +214,7 @@ http {
proxy_pass http://host.docker.internal:3001/resolve;
proxy_pass_request_body off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host "accounts.localhost";
proxy_set_header X-Forwarded-Host "accounts.portal.localhost:3100";
proxy_set_header Content-Length "";
}
}
Expand Down
23 changes: 9 additions & 14 deletions pkg/admin/facade/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,7 @@ type OAuthTokenService interface {
) (offlineGrant *oauth.OfflineGrant, tokenHash string, err error)
IssueAccessGrant(
ctx context.Context,
client *config.OAuthClientConfig,
scopes []string,
authzID string,
userID string,
sessionID string,
sessionKind oauth.GrantSessionKind,
refreshTokenHash string,
options oauth.IssueAccessGrantOptions,
resp protocol.TokenResponse,
) error
}
Expand Down Expand Up @@ -108,13 +102,14 @@ func (f *OAuthFacade) CreateSession(ctx context.Context, clientID string, userID

err = f.Tokens.IssueAccessGrant(
ctx,
client,
scopes,
authz.ID,
authz.UserID,
offlineGrant.ID,
oauth.GrantSessionKindOffline,
tokenHash,
oauth.IssueAccessGrantOptions{
ClientConfig: client,
Scopes: scopes,
AuthorizationID: authz.ID,
AuthenticationInfo: offlineGrant.GetAuthenticationInfo(),
SessionLike: offlineGrant,
RefreshTokenHash: tokenHash,
},
resp,
)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/auth/handler/saml/logout.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

"github.com/authgear/authgear-server/pkg/lib/config"
"github.com/authgear/authgear-server/pkg/lib/infra/db/appdb"
"github.com/authgear/authgear-server/pkg/lib/oauth/oidc"
"github.com/authgear/authgear-server/pkg/lib/oauth"
"github.com/authgear/authgear-server/pkg/lib/saml"
"github.com/authgear/authgear-server/pkg/lib/saml/samlbinding"
"github.com/authgear/authgear-server/pkg/lib/saml/samlprotocol"
Expand Down Expand Up @@ -405,7 +405,7 @@ func (h *LogoutHandler) invalidateSession(
affectedServiceProviderIDs setutil.Set[string],
err error,
) {
_, sessionID, ok := oidc.DecodeSID(sid)
_, sessionID, ok := oauth.DecodeSID(sid)
if ok {
s, err := h.SessionManager.Get(ctx, sessionID)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/auth/handler/webapp/logout.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/authgear/authgear-server/pkg/auth/webapp"
"github.com/authgear/authgear-server/pkg/lib/config"
"github.com/authgear/authgear-server/pkg/lib/infra/db/appdb"
"github.com/authgear/authgear-server/pkg/lib/oauth/oidc"
"github.com/authgear/authgear-server/pkg/lib/oauth"
"github.com/authgear/authgear-server/pkg/lib/saml/samlslosession"
"github.com/authgear/authgear-server/pkg/lib/session"
"github.com/authgear/authgear-server/pkg/lib/uiparam"
Expand Down Expand Up @@ -101,7 +101,7 @@ func (h *LogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if len(pendingLogoutServiceProviderIDs.Keys()) > 0 {
sloSessionEntry := &samlslosession.SAMLSLOSessionEntry{
PendingLogoutServiceProviderIDs: pendingLogoutServiceProviderIDs.Keys(),
SID: oidc.EncodeSID(sess),
SID: oauth.EncodeSID(sess),
UserID: sess.GetAuthenticationInfo().UserID,
PostLogoutRedirectURI: redirectURI,
}
Expand Down
28 changes: 28 additions & 0 deletions pkg/lib/oauth/grant.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
package oauth

import (
"fmt"

"github.com/authgear/authgear-server/pkg/lib/session"
)

type GrantSessionKind string

const (
GrantSessionKindOffline GrantSessionKind = "offline_grant"
GrantSessionKindSession GrantSessionKind = "idp_session"
)

func (k GrantSessionKind) SessionType() session.Type {
switch k {
case GrantSessionKindSession:
return session.TypeIdentityProvider
case GrantSessionKindOffline:
return session.TypeOfflineGrant
default:
panic(fmt.Errorf("unknown session kind: %v\n", k))
}
}

func GrantSessionKindFromSessionType(typ session.Type) GrantSessionKind {
switch typ {
case session.TypeIdentityProvider:
return GrantSessionKindSession
case session.TypeOfflineGrant:
return GrantSessionKindOffline
default:
panic(fmt.Errorf("unknown session type: %v", typ))
}
}
Loading