saml-passthrough/session_provider.go

76 lines
1.7 KiB
Go

// adapted from https://github.com/crewjam/saml/blob/main/samlidp/session.go
package main
import (
"encoding/base64"
"encoding/hex"
"log"
"net/http"
"net/http/fcgi"
"strings"
"time"
"github.com/crewjam/saml"
)
var sessionMaxAge = time.Hour
func randomBytes(n int) []byte {
rv := make([]byte, n)
if _, err := saml.RandReader.Read(rv); err != nil {
panic(err)
}
return rv
}
type User struct {
Username string
Email string
GivenName string
Surname string
Groups []string
}
type BasicSessionProvider struct {
UsernameKey string
EmailKey string
GivenNameKey string
SurnameKey string
GroupsKey string
}
func (s *BasicSessionProvider) getUser(r *http.Request) *User {
env := fcgi.ProcessEnv(r)
user := &User{}
user.Username, _ = env[s.UsernameKey]
user.Email, _ = env[s.EmailKey]
user.GivenName, _ = env[s.GivenNameKey]
user.Surname, _ = env[s.SurnameKey]
groupsStr, _ := env[s.GroupsKey]
user.Groups = strings.Split(groupsStr, ";")
return user
}
func (s *BasicSessionProvider) GetSession(w http.ResponseWriter, r *http.Request, req *saml.IdpAuthnRequest) *saml.Session {
user := s.getUser(r)
if user.Username == "" {
log.Println("Could not obtain username from FCGI")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return nil
}
session := &saml.Session{
ID: base64.StdEncoding.EncodeToString(randomBytes(32)),
NameID: user.Username,
CreateTime: saml.TimeNow(),
ExpireTime: saml.TimeNow().Add(sessionMaxAge),
Index: hex.EncodeToString(randomBytes(32)),
UserName: user.Username,
Groups: user.Groups,
UserEmail: user.Email,
UserSurname: user.Surname,
UserGivenName: user.GivenName,
}
return session
}