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

OpenID Connect (oidc) support #332

Open
oliverpool opened this issue Feb 10, 2022 · 2 comments
Open

OpenID Connect (oidc) support #332

oliverpool opened this issue Feb 10, 2022 · 2 comments

Comments

@oliverpool
Copy link

oliverpool commented Feb 10, 2022

OpenID Connect seems like an easier way to offer login than oauth2.

If you think that this is a good idea, I could try to add it as a subpackage github.com/volatiletech/authboss/v3/oauth2/oidc.

Here is my current implementation (based on https://github.com/caos/oidc):

package oidc

import (
	"context"
	"fmt"
	"net/http"
	"time"

	"github.com/caos/oidc/pkg/client"
	httphelper "github.com/caos/oidc/pkg/http"
	caosoidc "github.com/caos/oidc/pkg/oidc"
	"github.com/volatiletech/authboss/v3"
	aboauth2 "github.com/volatiletech/authboss/v3/oauth2"
	"golang.org/x/oauth2"
)

// NewProvider discovers the configuration of the OpenID Connect provider, based on issuer.
func NewProvider(issuer, clientID, clientSecret string, scopes []string) (authboss.OAuth2Provider, error) {
	cfg := &oauth2.Config{
		ClientID:     clientID,
		ClientSecret: clientSecret,
		RedirectURL:  "", // will be filled later during init
		Scopes:       scopes,
	}
	httpClient := &http.Client{
		Timeout: 30 * time.Second,
	}

	dicovered, err := client.Discover(issuer, httpClient)
	if err != nil {
		return authboss.OAuth2Provider{}, err
	}
	cfg.Endpoint = oauth2.Endpoint{
		AuthURL:   dicovered.AuthorizationEndpoint,
		TokenURL:  dicovered.TokenEndpoint,
	}

	return authboss.OAuth2Provider{
		OAuth2Config: cfg,
		FindUserDetails: func(ctx context.Context, cfg oauth2.Config, token *oauth2.Token) (map[string]string, error) {
			req, err := http.NewRequest("GET", dicovered.UserinfoEndpoint, nil)
			if err != nil {
				return nil, err
			}
			req.Header.Set("authorization", token.TokenType+" "+token.AccessToken)
			userinfo := caosoidc.NewUserInfo()
			if err := httphelper.HttpRequest(httpClient, req, &userinfo); err != nil {
				return nil, err
			}

			user := map[string]string{
				aboauth2.OAuth2UID: userinfo.GetSubject(),
			}
			if email := userinfo.GetEmail(); email != "" {
				user[aboauth2.OAuth2Email] = email
			}

			return user, nil
		},
	}, nil
}
@aarondl
Copy link
Member

aarondl commented Feb 13, 2022

If you want to champion this then I'm all for it. Just improves Authboss in general so I think that's great. I don't have any experience with OpenID Connect but it does seem quite popular.

@oliverpool
Copy link
Author

I have created an external module to experiment on this: https://pkg.go.dev/git.sr.ht/~oliverpool/goath

It seems to work fine in my case, but I would really appreciate a review!

import "git.sr.ht/~oliverpool/goath/goauthboss"

// ...

	ab = authboss.New()
	goauthboss.Init(ab, map[string]goath.Provider{
		"oidc": &coreos.OIDC{...},
	}, store)

In there, I also did the cleanup that I suggested here: #333 (comment)

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

No branches or pull requests

2 participants