# README
openid
-- import "github.com/autom8ter/openid"
Example
import (
"github.com/autom8ter/openid"
"log"
"net/http"
"os"
)
func main() {
config, err := openid.NewConfig(&openid.Opts{
DiscoveryUrl: os.Getenv("OPENID_TEST_DISCOVERY_URL"), // ex: https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration
ClientID: os.Getenv("OPENID_TEST_CLIENT_ID"),
ClientSecret: os.Getenv("OPENID_TEST_CLIENT_SECRET"), //do not commit to code
Redirect: os.Getenv("OPENID_TEST_REDIRECT"), //localhost:8080/login
Scopes: openid.DefaultScopes,
SkipIssuerCheck: true,
})
if err != nil {
log.Fatal(err.Error())
}
const (
logout = "/logout"
home = "/home" //this is a protected route that cannot be accessed unless they have logged in
login = "/login" //this is where the identity provider will redirect the user to after they login
authorization = "/login/authorization" //redirects the user to login to the identity provider
)
mux := http.NewServeMux()
mux.HandleFunc(logout, func(w http.ResponseWriter, r *http.Request) {
openid.Logout(w, r) //clear user session
w.Write([]byte("logged out!"))
})
mux.HandleFunc(authorization, config.HandleAuthorizationRedirect())
//protected, will redirect to authorization if not logged in.
mux.HandleFunc(home, openid.Middleware(func(w http.ResponseWriter, r *http.Request) {
usr, err := config.GetUser(r)
if err != nil {
http.Error(w, "failed to get user", http.StatusInternalServerError)
return
}
w.Write([]byte(usr.String()))
}, authorization))
//this is the oauth2 callback that will redirect to home after login
mux.HandleFunc(login, config.HandleLogin(home, func(u *openid.AuthUser, r *http.Request) error {
log.Print(u.ToUser().String())
return nil
}))
http.ListenAndServe(":8080", mux)
}
Usage
var (
//DefaultScopes are added if a Configs scopes are empty, they include: openid, email, profile
DefaultScopes = []string{"openid", "email", "profile"}
)
func GetSession
func GetSession(r *http.Request) (*sessions.Session, error)
func Logout
func Logout(w http.ResponseWriter, r *http.Request)
Logout logs the user out so they cant pass the middleware without authenticating against at least one idp
func Middleware
func Middleware(handler http.HandlerFunc, redirect string) http.HandlerFunc
Middleware wraps the http handler and redirects the user to the redirect if they are not logged in
func SetSession
func SetSession(store *sessions.CookieStore)
SetSession overrides the default session store(recommended for production usage)
type AuthUser
type AuthUser struct {
AuthToken *oauth2.Token
IDToken map[string]interface{}
UserInfo map[string]interface{}
}
func (AuthUser) ToUser
func (u AuthUser) ToUser() *User
type Config
type Config struct {
}
Config is used to to complete the Open ID Connect protocol using the Authorization Grant Authentication Flow.
func NewConfig
func NewConfig(opts *Opts) (*Config, error)
NewConfig creates a new Config from the given options
func (*Config) Exchange
func (c *Config) Exchange(ctx context.Context, code string) (*AuthUser, error)
Exchange gets an AuthUser type by exchanging the authorization code for an access & id token, then calling the userinfo endpoint
func (*Config) GetSession
func (c *Config) GetSession(r *http.Request) (*sessions.Session, error)
func (*Config) GetUser
func (c *Config) GetUser(r *http.Request) (*User, error)
func (*Config) HandleAuthorizationRedirect
func (c *Config) HandleAuthorizationRedirect() http.HandlerFunc
HandleAuthorizationRedirect is an http handler that redirects the user to the identity providers login screen
func (*Config) HandleLogin
func (c *Config) HandleLogin(redirect string, onLogins ...OnLoginFunc) http.HandlerFunc
HandleLogin gets the user from the request, executes the LoginHandler and then redirects to the input redirect
func (*Config) Issuer
func (c *Config) Issuer() string
OAuth2 returns the Configs issuer returned from the discovery endpoint
func (*Config) OAuth2
func (c *Config) OAuth2() *oauth2.Config
OAuth2 returns a pointer to the Configs oauth2.Config
func (*Config) UserInfoUrl
func (c *Config) UserInfoUrl() string
OAuth2 returns the Configs user info url returned from the discovery endpoint
type OnLoginFunc
type OnLoginFunc func(u *AuthUser, r *http.Request) error
OnLoginFunc may be optionally passed into config.HandleLogin in order to execute additional logic against the user after the login occurs
type Opts
type Opts struct {
// OpenID Connect describes a metadata document that contains most of the information required for an app to do sign-in.
// ex: https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration
DiscoveryUrl string
// ClientID is the application's ID.
ClientID string
// ClientSecret is the application's secret.
ClientSecret string
// RedirectURL is the URL to redirect users going through
// the OAuth flow, after the resource owner's URLs.
Redirect string
// Scope specifies optional requested permissions.
Scopes []string
// SkipIssuerCheck skips the openid issuer check
SkipIssuerCheck bool
}
Opts are options used when creating a new Configuration
type User
type User struct {
IDToken map[string]interface{} `json:"id_token"`
UserInfo map[string]interface{} `json:"user_info"`
}
User is a combination of the IDToken and the data returned from the UserInfo endpoint
func (*User) String
func (o *User) String() string