authboss icon indicating copy to clipboard operation
authboss copied to clipboard

OpenID Connect (oidc) support

Open oliverpool opened this issue 3 years ago • 2 comments

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
}

oliverpool avatar Feb 10 '22 11:02 oliverpool

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.

aarondl avatar Feb 13 '22 17:02 aarondl

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: https://github.com/volatiletech/authboss/issues/333#issuecomment-1034989236

oliverpool avatar Feb 17 '22 15:02 oliverpool