Add support to login using identity from an identity-aware proxy #715
|
@ -18,12 +18,12 @@ package identityawareproxy
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/modules/auth"
|
||||
"code.vikunja.io/api/pkg/modules/keyvalue"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
@ -35,40 +35,32 @@ import (
|
|||
var TimeFunc = time.Now
|
||||
|
||||
// Caches the public keys of the identity-aware proxy used to validate the auth data it sends
|
||||
|
||||
type iapCache struct {
|
||||
keyset *jwk.Set
|
||||
mutex sync.Mutex
|
||||
}
|
||||
const iapCacheKey = "iapcache_keyset"
|
||||
|
||||
// GetKeyset returns the cached public keys from the identity-aware proxy
|
||||
// or fetches them for the first time.
|
||||
func (cache *iapCache) GetKeyset() (*jwk.Set, error) {
|
||||
if cache.keyset != nil {
|
||||
return cache.keyset, nil
|
||||
func GetKeyset() (keyset *jwk.Set, err error) {
|
||||
k, exists, err := keyvalue.Get(iapCacheKey)
|
||||
if !exists {
|
||||
// Fetch the public key(s) from the identity-aware proxy
|
||||
keyset, err = jwk.FetchHTTP(config.AuthIdentityAwareProxyJwksURI.GetString())
|
||||
if err != nil {
|
||||
log.Error("Failed to retrieve the identity-aware proxy's signing public key at URL %s: %v", config.AuthIdentityAwareProxyJwksURI.GetString(), err)
|
||||
return nil, ErrIAPPublicKeysetMissing{URL: config.AuthIdentityAwareProxyJwksURI.GetString()}
|
||||
}
|
||||
keyvalue.Put(iapCacheKey, keyset)
|
||||
}
|
||||
|
||||
cache.mutex.Lock()
|
||||
defer cache.mutex.Unlock()
|
||||
|
||||
// Check that another thread has not fetched the keyset
|
||||
if cache.keyset != nil {
|
||||
return cache.keyset, nil
|
||||
if k != nil {
|
||||
return k.(*jwk.Set), nil
|
||||
}
|
||||
|
||||
// Fetch the public key(s) from the identity-aware proxy
|
||||
keyset, err := jwk.FetchHTTP(config.AuthIdentityAwareProxyJwksURI.GetString())
|
||||
if err != nil {
|
||||
log.Error("Failed to retrieve the identity-aware proxy's signing public key at URL %s: %v", config.AuthIdentityAwareProxyJwksURI.GetString(), err)
|
||||
return nil, ErrIAPPublicKeysetMissing{URL: config.AuthIdentityAwareProxyJwksURI.GetString()}
|
||||
}
|
||||
cache.keyset = keyset
|
||||
return cache.keyset, nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// The identity-aware proxy authentication middleware parses and validates the
|
||||
// JWT provided by the IAP
|
||||
func Middleware() echo.MiddlewareFunc {
|
||||
cache := &iapCache{}
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
// Skip if IAP is not enabled
|
||||
|
@ -83,7 +75,7 @@ func Middleware() echo.MiddlewareFunc {
|
|||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
keyset, err := cache.GetKeyset()
|
||||
keyset, err := GetKeyset()
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user
Please use the
keyvalue
package for this.