Skip to content

Commit

Permalink
Merge pull request #4 from TJM/sessions3
Browse files Browse the repository at this point in the history
Sessions3
  • Loading branch information
Tommy McNeely authored Feb 2, 2021
2 parents d3b183f + c473dde commit e0ce988
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 92 deletions.
60 changes: 42 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ package main
import (
"fmt"
"net/http"
"os"

oidcauth "github.com/TJM/gin-gonic-oidcauth"
"github.com/gin-contrib/sessions"
Expand All @@ -47,35 +48,58 @@ import (
func main() {
r := gin.Default()

// NOTE: DefaultConfig uses Google Accounts - See https://github.com/coreos/go-oidc/blob/v3/example/README.md
authConfig := oidcauth.DefaultConfig()
auth, err := authConfig.GetOidcAuth()
// Session Config (Basic cookies)
store := cookie.NewStore([]byte("secret"), nil) // Do not use "secret", nil in production. This sets the keypairs for auth, encryption of the cookies.
r.Use(sessions.Sessions("mysession", store)) // Sessions must be Use(d) before oidcauth, as oidcauth requires sessions

// NOTE: DefaultConfig uses Google Accounts
// - See https://github.com/coreos/go-oidc/blob/v3/example/README.md
auth, err := oidcauth.GetOidcAuth(oidcauth.DefaultConfig())
if err != nil {
panic("auth setup failed")
}
if os.Getenv("DEBUG") != "" {
auth.Debug = true
}

// Session Config (Basic cookies)
store := cookie.NewStore([]byte("secret"), nil) // Do not use "secret" in production
r.Use(sessions.Sessions("mysession", store))
r.GET("/login", auth.Login) // Unnecessary, as requesting a "AuthRequired" resource will initiate login, but potentially convenient
r.GET("/auth/google/callback", auth.AuthCallback)
r.GET("/logout", auth.Logout)

// Allow access to / for unauthenticated users, but authenticated users will be greated by name.
r.GET("/", func(c *gin.Context) {

session := sessions.Default(c)
var name string

name := "world"
n := session.Get("name")
if n == nil {
name = "world"
} else {
if n != nil {
name = n.(string)
}

session.Save()
out := fmt.Sprintf("Hello, %s.\n", name)
c.String(http.StatusOK, out)
// session.Save() // if it has been changed, which it has not
c.String(http.StatusOK, fmt.Sprintf("Hello, %s.", name))
})
r.GET("/auth/google/login", auth.AuthLoginHandler)
r.GET("/auth/google/callback", auth.AuthCallbackHandler)

private := r.Group("/private", auth.AuthRequired())
{
private.GET("", func(c *gin.Context) {
var name, email, out string
login := c.GetString(oidcauth.AuthUserKey)
session := sessions.Default(c)
n := session.Get("name")
if n == nil {
name = "Someone without a name?"
} else {
name = n.(string)
}
e := session.Get("email")
if e != nil {
email = e.(string)
}
out = fmt.Sprintf("Hello, %s <%s>.\nLogin: %s\n", name, email, login)
// session.Save() // if it has been changed, which it has not
c.String(http.StatusOK, out)
return
})
}

r.Run(":5556")
}
Expand Down
64 changes: 58 additions & 6 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,46 @@ type Config struct {
// Scopes is a list of OIDC Scopes to request.
// Default value is: []string{oidc.ScopeOpenID, "profile", "email"}
Scopes []string

// LoginClaim is the OIDC claim to map to the user's login (username)
// Default value is: "email"
LoginClaim string

// SessionClaims is the list of OIDC claims to add to the user's session (in addition to LoginClaim)
// Example []string{"email", "givenName", "name"}
// NOTE: This can be set to ["*"] to load *all* claims. (nonce will be excluded)
// Default value is: ["*"]
SessionClaims []string

// SessionPrefix is an optional prefix string to prefix to the claims (i.e. google: or corp:) to prevent
// clashes in the session namespace
// Default value is: ""
SessionPrefix string

// DefaultAuthenticatedURL is the URL to redirect a user to after successful authentication. By default, we will
// try to determine where they were when they requested to login and send them back there.
// Default value is: "/"
DefaultAuthenticatedURL string

// LogoutURL is the URL to redirect a user to after logging out.
// NOTE: If you require / to be authenticated, setting this to / will start the login process immediately, which may not be desirable.
// Default value is: "/"
LogoutURL string
}

// DefaultConfig will create a new config object with defaults
// NOTE: This matches the examples on https://github.com/coreos/go-oidc/tree/v3/example
func DefaultConfig() (c *Config) {
c = &Config{
ClientID: os.Getenv("GOOGLE_OAUTH2_CLIENT_ID"),
ClientSecret: os.Getenv("GOOGLE_OAUTH2_CLIENT_SECRET"),
IssuerURL: "https://accounts.google.com",
RedirectURL: "http://127.0.0.1:5556/auth/google/callback",
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
ClientID: os.Getenv("GOOGLE_OAUTH2_CLIENT_ID"),
ClientSecret: os.Getenv("GOOGLE_OAUTH2_CLIENT_SECRET"),
IssuerURL: "https://accounts.google.com",
RedirectURL: "http://127.0.0.1:5556/auth/google/callback",
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
LoginClaim: "email",
SessionClaims: []string{"*"},
DefaultAuthenticatedURL: "/",
LogoutURL: "/",
}
return
}
Expand Down Expand Up @@ -70,11 +99,34 @@ func (c Config) Validate() (err error) {
return
}

// GetOidcAuth returns the configured OIDC authentication controller?
// GetOidcAuth returns the configured OIDC authentication controller
func GetOidcAuth(c *Config) (o *OidcAuth, err error) {
return c.GetOidcAuth()
}

// GetOidcAuth returns the configured OIDC authentication controller
func (c *Config) GetOidcAuth() (o *OidcAuth, err error) {
err = c.Validate()
if err != nil {
log.Fatal(err)
}
return newOidcAuth(c)
}

// The methods below can be used to return the middleware, but currently do
// not handle the routes. They are of limited use, for now.
//
// // Default returns the location middleware with default configuration.
// func Default() gin.HandlerFunc {
// config := DefaultConfig()
// return New(config)
// }

// // New returns the location middleware with user-defined custom configuration.
// func New(c *Config) gin.HandlerFunc {
// auth, err := c.GetOidcAuth()
// if err != nil {
// log.Fatal("[oidcauth] Error getting auth handler")
// }
// return auth.AuthRequired()
// }
60 changes: 38 additions & 22 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,58 @@ import (
func main() {
r := gin.Default()

// NOTE: DefaultConfig uses Google Accounts - See https://github.com/coreos/go-oidc/blob/v3/example/README.md
authConfig := oidcauth.DefaultConfig()
auth, err := authConfig.GetOidcAuth()
// Session Config (Basic cookies)
store := cookie.NewStore([]byte("secret"), nil) // Do not use "secret", nil in production. This sets the keypairs for auth, encryption of the cookies.
r.Use(sessions.Sessions("mysession", store)) // Sessions must be Use(d) before oidcauth, as oidcauth requires sessions

// NOTE: DefaultConfig uses Google Accounts
// - See https://github.com/coreos/go-oidc/blob/v3/example/README.md
auth, err := oidcauth.GetOidcAuth(oidcauth.DefaultConfig())
if err != nil {
panic("auth setup failed")
}
if os.Getenv("DEBUG") != "" {
auth.Debug = true
}

// Session Config (Basic cookies)
store := cookie.NewStore([]byte("secret"), nil) // Do not use "secret", nil in production
r.Use(sessions.Sessions("mysession", store))
r.GET("/login", auth.Login) // Unnecessary, as requesting a "AuthRequired" resource will initiate login, but potentially convenient
r.GET("/auth/google/callback", auth.AuthCallback)
r.GET("/logout", auth.Logout)

// Allow access to / for unauthenticated users, but authenticated users will be greated by name.
r.GET("/", func(c *gin.Context) {
var name, email, out string
session := sessions.Default(c)
name := "world"
n := session.Get("name")
if n == nil {
name = "world"
} else {
if n != nil {
name = n.(string)
}
e := session.Get("email")
if n == nil {
email = ""
out = fmt.Sprintf("Hello, %s.\n", name)
} else {
email = e.(string)
out = fmt.Sprintf("Hello, %s <%s>.\n", name, email)
}
// session.Save()
c.String(http.StatusOK, out)
// session.Save() // if it has been changed, which it has not
c.String(http.StatusOK, fmt.Sprintf("Hello, %s.", name))
})
r.GET("/auth/google/login", auth.AuthLoginHandler)
r.GET("/auth/google/callback", auth.AuthCallbackHandler)

private := r.Group("/private", auth.AuthRequired())
{
private.GET("", func(c *gin.Context) {
var name, email, out string
login := c.GetString(oidcauth.AuthUserKey)
session := sessions.Default(c)
n := session.Get("name")
if n == nil {
name = "Someone without a name?"
} else {
name = n.(string)
}
e := session.Get("email")
if e != nil {
email = e.(string)
}
out = fmt.Sprintf("Hello, %s <%s>.\nLogin: %s\n", name, email, login)
// session.Save() // if it has been changed, which it has not
c.String(http.StatusOK, out)
return
})
}

r.Run(":5556")
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/gin-gonic/gin v1.6.3
github.com/gorilla/sessions v1.2.1 // indirect
github.com/letsencrypt/boulder v0.0.0-20210130012035-2a8f0fe6ac7e
github.com/sirupsen/logrus v1.4.2
golang.org/x/net v0.0.0-20210119194325-5f4716e94777
golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ github.com/kidstuff/mongostore v0.0.0-20181113001930-e650cd85ee4b/go.mod h1:g2nV
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
Expand Down Expand Up @@ -258,6 +259,7 @@ github.com/quasoft/memstore v0.0.0-20180925164028-84a050167438/go.mod h1:wTPjTep
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
Loading

0 comments on commit e0ce988

Please sign in to comment.