-
Notifications
You must be signed in to change notification settings - Fork 25
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
Single Sign-on #39
Comments
Hey! Yeah, some kind of SSO, probably via OIDC, would be nice and is certainly on the roadmap. As I see it there are a couple approaches:
I feel like approach 1 is probably going to be the best option, although approach 3 would be pretty cool. |
I personally think the first option is ideal. Already, Minecraft username is separate from drasl login name, this would also match how MC username is separate from Microsoft/Mojang email/userid. It'd also allow people to change their usernames in SSO-managed accounts. Also, I do agree that OIDC would be the best option. |
Additionally, an option to migrate/link existing accounts/usernames on first sign-in to SSO would be awesome! Perhaps on first SSO sign-in, if there are non-SSO accounts, there is an option to sign in with the "local" account, if that is done the user data is transferred from the local account and then the local account is deleted. That is definitely not essential, though. Could just make everyone recreate their accounts haha. |
any update on this, this would be great! |
Support for multiple players (#75) has been my focus recently and it's almost done (#107). I'm planning to bump the major version to 3.0.0 when that's released. OIDC is next on my list. I may try to play around with OIDC before releasing 3.0.0; if it turns out to be easy to implement and/or it makes API-breaking changes, it'd be nice to just include it in 3.0.0. I'm planning to work on this over the holidays :) |
Very cool, thanks for your amazing work on this! I think oidc would not be too much work, for a other project im using https://github.com/coreos/go-oidc which is pretty simple to use. I added a code snippet the way I would use it. from there you would just need to implement the DB/session management correctly. maybe it helps.package main
import (
"context"
"errors"
"log"
"net/http"
"time"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/labstack/echo/v4"
"golang.org/x/oauth2"
)
var OidcConfig *oauth2.Config
var OidcProvider *oidc.Provider
var OidcVerifier *oidc.IDTokenVerifier
func setupOidc(app *App) {
ctx := context.Background()
var err error
OidcProvider, err = oidc.NewProvider(ctx, app.Config.Oidc.Issuer)
if err != nil {
log.Fatal("Error connecting to oidc provider", err)
}
oidcConfig := &oidc.Config{
ClientID: app.Config.Oidc.ClientID,
}
OidcConfig = &oauth2.Config{
ClientID: app.Config.Oidc.ClientID,
ClientSecret: app.Config.Oidc.ClientSecret,
RedirectURL: app.Config.BaseURL + "/oidc-callback",
Endpoint: OidcProvider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
}
OidcVerifier = OidcProvider.Verifier(oidcConfig)
}
// BaseURL + '/oidc-callback'
func OidcCallback(app *App) func(c echo.Context) error {
return func(c echo.Context) (err error) {
ctx := context.Background()
stateCookie, err := c.Cookie("state")
if c.QueryParam("state") != stateCookie.Value {
return errors.New("invalid state")
}
if err != nil {
return err
}
oauth2Token, err := OidcConfig.Exchange(ctx, c.QueryParam("code"))
if err != nil {
return err
}
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
return err
}
idToken, err := OidcVerifier.Verify(ctx, rawIDToken)
if err != nil {
return err
}
var claims struct {
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
Name string `json:"name"`
Username string `json:"preferred_username"`
}
err = idToken.Claims(&claims)
if err != nil {
return err
}
// TODO do stuff here with the claims, and create a session for the user
return nil
}
}
// when the login button gets clicked, handle a redirect to the oidc provider
func OidcRedirect(app *App) func(c echo.Context) error {
return func(c echo.Context) (err error) {
state, err := RandomHex(16)
if err != nil {
return err
}
c.SetCookie(&http.Cookie{
Name: "state",
Value: state,
MaxAge: int(time.Hour.Seconds()),
Secure: true,
HttpOnly: true,
})
return c.Redirect(http.StatusFound, OidcConfig.AuthCodeURL(state))
}
} |
Remaining work is hinted by some TODO comments. Login still unimplemented (only registration works). For unmojang#39
Hi! I am currently using this behind oauth2-proxy with Keycloak, but would love the ability to integrate directly with OpenID Connect, SAML, or plain old LDAP.
The text was updated successfully, but these errors were encountered: