diff --git a/.golangci.yml b/.golangci.yml index 23f37cbf..20d35d9a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -38,7 +38,7 @@ linters: - depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false] linters-settings: goimports: - local-prefixes: github.com/crewjam/saml + local-prefixes: github.com/lorodoes/saml govet: disable: - shadow diff --git a/README.md b/README.md index c0b98058..e8c784ee 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # SAML -[![](https://godoc.org/github.com/crewjam/saml?status.svg)](http://godoc.org/github.com/crewjam/saml) +[![](https://godoc.org/github.com/lorodoes/saml?status.svg)](http://godoc.org/github.com/lorodoes/saml) -![Build Status](https://github.com/crewjam/saml/workflows/Presubmit/badge.svg) +![Build Status](https://github.com/lorodoes/saml/workflows/Presubmit/badge.svg) Package saml contains a partial implementation of the SAML standard in golang. SAML is a standard for identity federation, i.e. either allowing a third party to authenticate your users or allowing third parties to rely on us to authenticate their users. @@ -54,7 +54,7 @@ import ( "net/http" "net/url" - "github.com/crewjam/saml/samlsp" + "github.com/lorodoes/saml/samlsp" ) func hello(w http.ResponseWriter, r *http.Request) { diff --git a/example/idp/idp.go b/example/idp/idp.go index 4e47a56a..a81614d2 100644 --- a/example/idp/idp.go +++ b/example/idp/idp.go @@ -11,8 +11,8 @@ import ( "github.com/zenazn/goji" "golang.org/x/crypto/bcrypt" - "github.com/crewjam/saml/logger" - "github.com/crewjam/saml/samlidp" + "github.com/lorodoes/saml/logger" + "github.com/lorodoes/saml/samlidp" ) var key = func() crypto.PrivateKey { diff --git a/example/service.go b/example/service.go index 5b6ddb27..ab69ecdc 100644 --- a/example/service.go +++ b/example/service.go @@ -19,7 +19,7 @@ import ( "github.com/zenazn/goji" "github.com/zenazn/goji/web" - "github.com/crewjam/saml/samlsp" + "github.com/lorodoes/saml/samlsp" ) var links = map[string]Link{} diff --git a/example/trivial/trivial.go b/example/trivial/trivial.go index 45f46080..738dc28e 100644 --- a/example/trivial/trivial.go +++ b/example/trivial/trivial.go @@ -12,7 +12,7 @@ import ( "net/url" "time" - "github.com/crewjam/saml/samlsp" + "github.com/lorodoes/saml/samlsp" ) var samlMiddleware *samlsp.Middleware diff --git a/go.mod b/go.mod index 39f9c8d2..199e7d95 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ -module github.com/crewjam/saml +module github.com/lorodoes/saml -go 1.19 +go 1.20 require ( github.com/beevik/etree v1.2.0 @@ -12,17 +12,24 @@ require ( github.com/mattermost/xml-roundtrip-validator v0.1.0 github.com/russellhaering/goxmldsig v1.4.0 github.com/stretchr/testify v1.8.4 + github.com/pkg/errors v0.9.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.0 + github.com/stretchr/testify v1.8.1 github.com/zenazn/goji v1.0.1 golang.org/x/crypto v0.18.0 gotest.tools v2.2.0+incompatible ) require ( + github.com/andybalholm/brotli v1.0.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/jonboulle/clockwork v0.2.2 // indirect github.com/kr/text v0.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index eaa1f8af..e1d00824 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,6 @@ +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beevik/etree v1.2.0 h1:l7WETslUG/T+xOPs47dtd6jov2Ii/8/OjCldk5fYfQw= github.com/beevik/etree v1.2.0/go.mod h1:aiPf89g/1k3AShMVAzriilpcE4R/Vuor90y83zVZWFc= @@ -13,6 +16,12 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -36,17 +45,24 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russellhaering/goxmldsig v1.4.0 h1:8UcDh/xGyQiyrW+Fq5t8f+l2DLB1+zlhYzkPUJ7Qhys= -github.com/russellhaering/goxmldsig v1.4.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw= +github.com/russellhaering/goxmldsig v1.2.0 h1:Y6GTTc9Un5hCxSzVz4UIWQ/zuVwDvzJk80guqzwx6Vg= +github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/zenazn/goji v1.0.1 h1:4lbD8Mx2h7IvloP7r2C0D6ltZP6Ufip8Hn0wmSK5LR8= github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed h1:YoWVYYAfvQ4ddHv3OKmIvX7NCAhFGTj62VP2l2kfBbA= +golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/identity_provider.go b/identity_provider.go index abaaad68..76097b62 100644 --- a/identity_provider.go +++ b/identity_provider.go @@ -21,8 +21,8 @@ import ( xrv "github.com/mattermost/xml-roundtrip-validator" dsig "github.com/russellhaering/goxmldsig" - "github.com/crewjam/saml/logger" - "github.com/crewjam/saml/xmlenc" + "github.com/lorodoes/saml/logger" + "github.com/lorodoes/saml/xmlenc" ) // Session represents a user session. It is returned by the diff --git a/identity_provider_test.go b/identity_provider_test.go index 9d06a4bb..292e9f22 100644 --- a/identity_provider_test.go +++ b/identity_provider_test.go @@ -28,9 +28,9 @@ import ( "github.com/golang-jwt/jwt/v4" dsig "github.com/russellhaering/goxmldsig" - "github.com/crewjam/saml/logger" - "github.com/crewjam/saml/testsaml" - "github.com/crewjam/saml/xmlenc" + "github.com/lorodoes/saml/logger" + "github.com/lorodoes/saml/testsaml" + "github.com/lorodoes/saml/xmlenc" ) type IdentityProviderTest struct { diff --git a/saml.go b/saml.go index b171e56d..2c1a12fb 100644 --- a/saml.go +++ b/saml.go @@ -11,7 +11,7 @@ // // Version 0.4.0 introduces a few breaking changes to the _samlsp_ package in order to make the package more extensible, and to clean up the interfaces a bit. The default behavior remains the same, but you can now provide interface implementations of _RequestTracker_ (which tracks pending requests), _Session_ (which handles maintaining a session) and _OnError_ which handles reporting errors. // -// Public fields of _samlsp.Middleware_ have changed, so some usages may require adjustment. See [issue 231](https://github.com/crewjam/saml/issues/231) for details. +// Public fields of _samlsp.Middleware_ have changed, so some usages may require adjustment. See [issue 231](https://github.com/lorodoes/saml/issues/231) for details. // // The option to provide an IDP metadata URL has been deprecated. Instead, we recommend that you use the `FetchMetadata()` function, or fetch the metadata yourself and use the new `ParseMetadata()` function, and pass the metadata in _samlsp.Options.IDPMetadata_. // @@ -76,7 +76,7 @@ // "net/http" // "net/url" // -// "github.com/crewjam/saml/samlsp" +// "github.com/lorodoes/saml/samlsp" // // ) // diff --git a/samlidp/samlidp.go b/samlidp/samlidp.go index 13ca10b9..0fe6b6d3 100644 --- a/samlidp/samlidp.go +++ b/samlidp/samlidp.go @@ -12,8 +12,8 @@ import ( "github.com/zenazn/goji/web" - "github.com/crewjam/saml" - "github.com/crewjam/saml/logger" + "github.com/lorodoes/saml" + "github.com/lorodoes/saml/logger" ) // Options represent the parameters to New() for creating a new IDP server diff --git a/samlidp/samlidp_test.go b/samlidp/samlidp_test.go index e5b2dafb..4ec591a7 100644 --- a/samlidp/samlidp_test.go +++ b/samlidp/samlidp_test.go @@ -18,8 +18,8 @@ import ( "github.com/golang-jwt/jwt/v4" - "github.com/crewjam/saml" - "github.com/crewjam/saml/logger" + "github.com/lorodoes/saml" + "github.com/lorodoes/saml/logger" ) type testRandomReader struct { diff --git a/samlidp/service.go b/samlidp/service.go index 0b62cd3b..9c2709ae 100644 --- a/samlidp/service.go +++ b/samlidp/service.go @@ -9,7 +9,7 @@ import ( "github.com/zenazn/goji/web" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) // Service represents a configured SP for whom this IDP provides authentication services. diff --git a/samlidp/session.go b/samlidp/session.go index 8ffae2ba..eb4613ac 100644 --- a/samlidp/session.go +++ b/samlidp/session.go @@ -13,7 +13,7 @@ import ( "github.com/zenazn/goji/web" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) var sessionMaxAge = time.Hour diff --git a/samlidp/util.go b/samlidp/util.go index 2cb3c162..94db8309 100644 --- a/samlidp/util.go +++ b/samlidp/util.go @@ -8,7 +8,7 @@ import ( xrv "github.com/mattermost/xml-roundtrip-validator" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) func randomBytes(n int) []byte { diff --git a/samlsp/error.go b/samlsp/error.go index 496faccf..0e017e03 100644 --- a/samlsp/error.go +++ b/samlsp/error.go @@ -4,7 +4,7 @@ import ( "log" "net/http" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) // ErrorFunction is a callback that is invoked to return an error to the diff --git a/samlsp/fetch_metadata.go b/samlsp/fetch_metadata.go index ede3c6b3..d5f4f29d 100644 --- a/samlsp/fetch_metadata.go +++ b/samlsp/fetch_metadata.go @@ -12,9 +12,8 @@ import ( "github.com/crewjam/httperr" xrv "github.com/mattermost/xml-roundtrip-validator" - "github.com/crewjam/saml/logger" - - "github.com/crewjam/saml" + "github.com/lorodoes/saml" + "github.com/lorodoes/saml/logger" ) // ParseMetadata parses arbitrary SAML IDP metadata. diff --git a/samlsp/middleware.go b/samlsp/middleware.go index f5eabb16..1739711b 100644 --- a/samlsp/middleware.go +++ b/samlsp/middleware.go @@ -5,7 +5,8 @@ import ( "encoding/xml" "net/http" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" + log "github.com/sirupsen/logrus" ) // Middleware implements middleware than allows a web application @@ -108,17 +109,22 @@ func (m *Middleware) ServeACS(w http.ResponseWriter, r *http.Request) { // to start the SAML auth flow. func (m *Middleware) RequireAccount(handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + log.Debugf("RequireAccount: Getting the Session") session, err := m.Session.GetSession(r) if session != nil { + log.Debugf("RequireAccount: Session Not nil") r = r.WithContext(ContextWithSession(r.Context(), session)) handler.ServeHTTP(w, r) return } if err == ErrNoSession { + log.Debugf("RequireAccount: Error No Session") + log.Debugf("RequireAccount: Error: %s", err) m.HandleStartAuthFlow(w, r) return } + log.Debugf("RequireAccount: error") m.OnError(w, r, err) }) } @@ -215,10 +221,12 @@ func (m *Middleware) CreateSessionFromAssertion(w http.ResponseWriter, r *http.R } if err := m.Session.CreateSession(w, r, assertion); err != nil { + log.Debugf("Error on CreateSession line 209, %s", err) m.OnError(w, r, err) return } + log.Debugf("Redirecting to URI") http.Redirect(w, r, redirectURI, http.StatusFound) } diff --git a/samlsp/middleware_test.go b/samlsp/middleware_test.go index fdb05b20..58b74be3 100644 --- a/samlsp/middleware_test.go +++ b/samlsp/middleware_test.go @@ -23,8 +23,8 @@ import ( is "gotest.tools/assert/cmp" "gotest.tools/golden" - "github.com/crewjam/saml" - "github.com/crewjam/saml/testsaml" + "github.com/lorodoes/saml" + "github.com/lorodoes/saml/testsaml" ) type MiddlewareTest struct { diff --git a/samlsp/new.go b/samlsp/new.go index 81fa75f6..9ba9c0c3 100644 --- a/samlsp/new.go +++ b/samlsp/new.go @@ -9,7 +9,7 @@ import ( dsig "github.com/russellhaering/goxmldsig" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) // Options represents the parameters for creating a new middleware diff --git a/samlsp/request_tracker_cookie.go b/samlsp/request_tracker_cookie.go index d9189f63..57f7dc1a 100644 --- a/samlsp/request_tracker_cookie.go +++ b/samlsp/request_tracker_cookie.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) var _ RequestTracker = CookieRequestTracker{} diff --git a/samlsp/request_tracker_jwt.go b/samlsp/request_tracker_jwt.go index 0ca47258..667306fe 100644 --- a/samlsp/request_tracker_jwt.go +++ b/samlsp/request_tracker_jwt.go @@ -7,7 +7,7 @@ import ( "github.com/golang-jwt/jwt/v4" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) var defaultJWTSigningMethod = jwt.SigningMethodRS256 diff --git a/samlsp/session.go b/samlsp/session.go index cd1da5d6..854234b8 100644 --- a/samlsp/session.go +++ b/samlsp/session.go @@ -5,7 +5,7 @@ import ( "errors" "net/http" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) // Session is an interface implemented to contain a session. diff --git a/samlsp/session_cookie.go b/samlsp/session_cookie.go index 4d557eee..022d9791 100644 --- a/samlsp/session_cookie.go +++ b/samlsp/session_cookie.go @@ -1,11 +1,19 @@ package samlsp import ( + "bytes" + "io" "net" "net/http" + "strings" "time" - "github.com/crewjam/saml" + b64 "encoding/base64" + + log "github.com/sirupsen/logrus" + + "github.com/andybalholm/brotli" + "github.com/lorodoes/saml" ) const defaultSessionCookieName = "token" @@ -28,37 +36,53 @@ type CookieSessionProvider struct { // should create a new session and modify the http response accordingly, e.g. by // setting a cookie. func (c CookieSessionProvider) CreateSession(w http.ResponseWriter, r *http.Request, assertion *saml.Assertion) error { + log.Debugf("Create Session") // Cookies should not have the port attached to them so strip it off if domain, _, err := net.SplitHostPort(c.Domain); err == nil { c.Domain = domain } + log.Debugf("Creating the assertion") session, err := c.Codec.New(assertion) if err != nil { + log.Debugf("Error Creating the assertion") return err } + log.Debugf("Encoding the Session") value, err := c.Codec.Encode(session) if err != nil { + log.Debugf("Error Encoding the Session") return err } - http.SetCookie(w, &http.Cookie{ + b := compressBrotli([]byte(value)) + + uEnc := b64.URLEncoding.EncodeToString(b) + + cookie := &http.Cookie{ Name: c.Name, Domain: c.Domain, - Value: value, + Value: uEnc, MaxAge: int(c.MaxAge.Seconds()), HttpOnly: c.HTTPOnly, Secure: c.Secure || r.URL.Scheme == "https", SameSite: c.SameSite, Path: "/", - }) + } + + log.Debugf("Setting the Cookie") + http.SetCookie(w, cookie) + log.Debugf("Log Response: %#v", w) + log.Debugf("Log Cookie: %#v", cookie) + log.Debugf("Cookie Set") return nil } // DeleteSession is called to modify the response such that it removed the current // session, e.g. by deleting a cookie. func (c CookieSessionProvider) DeleteSession(w http.ResponseWriter, r *http.Request) error { + log.Debugf("Delete Session") // Cookies should not have the port attached to them so strip it off if domain, _, err := net.SplitHostPort(c.Domain); err == nil { c.Domain = domain @@ -78,22 +102,52 @@ func (c CookieSessionProvider) DeleteSession(w http.ResponseWriter, r *http.Requ cookie.Path = "/" cookie.Domain = c.Domain http.SetCookie(w, cookie) + log.Debugf("Log Response: %#v", w) + log.Debugf("Log Cookie: %#v", cookie) return nil } // GetSession returns the current Session associated with the request, or // ErrNoSession if there is no valid session. func (c CookieSessionProvider) GetSession(r *http.Request) (Session, error) { + log.Debugf("Get Session") cookie, err := r.Cookie(c.Name) if err == http.ErrNoCookie { + log.Debugf("Get Session: Error No Session") + log.Debugf("Get Session: Error No Session: %s", err) return nil, ErrNoSession } else if err != nil { + log.Debugf("Get Session: Error") return nil, err } - session, err := c.Codec.Decode(cookie.Value) + uDec, _ := b64.URLEncoding.DecodeString(cookie.Value) + + d, _ := decompressBrotli(uDec) + + session, err := c.Codec.Decode(d) if err != nil { + log.Debugf("Get Session decode: Error No Session") return nil, ErrNoSession } + log.Debugf("Returning the session") return session, nil } + +func compressBrotli(data []byte) []byte { + var b bytes.Buffer + w := brotli.NewWriterLevel(&b, brotli.BestCompression) + w.Write(data) + w.Close() + return b.Bytes() +} + +func decompressBrotli(compressedData []byte) (string, error) { + reader := brotli.NewReader(bytes.NewReader(compressedData)) + var decompressedData strings.Builder + _, err := io.Copy(&decompressedData, reader) + if err != nil { + return "", err + } + return decompressedData.String(), nil +} diff --git a/samlsp/session_cookie_test.go b/samlsp/session_cookie_test.go index 74fcf2cb..9832c24f 100644 --- a/samlsp/session_cookie_test.go +++ b/samlsp/session_cookie_test.go @@ -8,7 +8,7 @@ import ( "gotest.tools/assert" is "gotest.tools/assert/cmp" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) func TestCookieSameSite(t *testing.T) { diff --git a/samlsp/session_jwt.go b/samlsp/session_jwt.go index 8d801e47..69c6eb8a 100644 --- a/samlsp/session_jwt.go +++ b/samlsp/session_jwt.go @@ -2,13 +2,19 @@ package samlsp import ( "crypto/rsa" + "encoding/json" "errors" "fmt" + "strings" "time" + log "github.com/sirupsen/logrus" + + "github.com/google/uuid" + "github.com/golang-jwt/jwt/v4" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) const ( @@ -38,7 +44,8 @@ func (c JWTSessionCodec) New(assertion *saml.Assertion) (Session, error) { claims.Audience = c.Audience claims.Issuer = c.Issuer claims.IssuedAt = now.Unix() - claims.ExpiresAt = now.Add(c.MaxAge).Unix() + expiresat := now.Add(c.MaxAge).Unix() + claims.ExpiresAt = expiresat claims.NotBefore = now.Unix() if sub := assertion.Subject; sub != nil { @@ -47,6 +54,7 @@ func (c JWTSessionCodec) New(assertion *saml.Assertion) (Session, error) { } } + Attributes := map[string][]string{} claims.Attributes = map[string][]string{} for _, attributeStatement := range assertion.AttributeStatements { @@ -56,7 +64,7 @@ func (c JWTSessionCodec) New(assertion *saml.Assertion) (Session, error) { claimName = attr.Name } for _, value := range attr.Values { - claims.Attributes[claimName] = append(claims.Attributes[claimName], value.Value) + Attributes[claimName] = append(Attributes[claimName], value.Value) } } } @@ -67,6 +75,26 @@ func (c JWTSessionCodec) New(assertion *saml.Assertion) (Session, error) { authnStatement.SessionIndex) } + log.Debugf("Attributes: %#v", Attributes) + + strExpiresAt := fmt.Sprintf("%d", expiresat) + + Attributes["ExpiresAtSAML"] = append(Attributes["ExpiresAtSAML"], strExpiresAt) + + log.Debugf("Turning claims in to json") + mapAsBytes, _ := json.Marshal(Attributes) + mapstring := string(mapAsBytes) + log.Debugf("attribute string: %s", mapstring) + log.Debugf("Create UUID") + id := uuid.New() + log.Debugf("Stringify UUID") + stringid := id.String() + log.Debugf("String into memory map") + saml.UserAttributes[stringid] = mapstring + log.Debugf("append string id in to attributes") + claims.Attributes["id"] = append(claims.Attributes["id"], stringid) + + log.Debugf("Returning Claims") return claims, nil } @@ -89,6 +117,7 @@ func (c JWTSessionCodec) Encode(s Session) (string, error) { // Decode parses the serialized session that may have been returned by Encode // and returns a Session. func (c JWTSessionCodec) Decode(signed string) (Session, error) { + log.Debugf("Starting Debug") parser := jwt.Parser{ ValidMethods: []string{c.SigningMethod.Alg()}, } @@ -96,6 +125,25 @@ func (c JWTSessionCodec) Decode(signed string) (Session, error) { _, err := parser.ParseWithClaims(signed, &claims, func(*jwt.Token) (interface{}, error) { return c.Key.Public(), nil }) + + UserId := claims.Attributes["id"] + log.Debugf("UserID: %s", UserId) + UserIdString := strings.Join(UserId, "") + log.Debugf("String UserID: %s", UserIdString) + mapstring, ok := saml.UserAttributes[UserIdString] + if !ok { + return nil, ErrNoSession + } + log.Debugf("map String: %#v", mapstring) + var attributes map[string][]string + json.Unmarshal([]byte(mapstring), &attributes) + log.Debugf("Map: %#v", attributes) + for k, v := range attributes { + log.Debugf("key: %s", k) + log.Debugf("value: %s", v) + claims.Attributes[k] = v + } + // TODO(ross): check for errors due to bad time and return ErrNoSession if err != nil { return nil, err diff --git a/samlsp/util.go b/samlsp/util.go index e1fa69ae..d5068f1b 100644 --- a/samlsp/util.go +++ b/samlsp/util.go @@ -3,7 +3,7 @@ package samlsp import ( "io" - "github.com/crewjam/saml" + "github.com/lorodoes/saml" ) func randomBytes(n int) []byte { diff --git a/service_provider.go b/service_provider.go index 30b35670..ab57f0c2 100644 --- a/service_provider.go +++ b/service_provider.go @@ -23,8 +23,8 @@ import ( dsig "github.com/russellhaering/goxmldsig" "github.com/russellhaering/goxmldsig/etreeutils" - "github.com/crewjam/saml/logger" - "github.com/crewjam/saml/xmlenc" + "github.com/lorodoes/saml/logger" + "github.com/lorodoes/saml/xmlenc" ) // NameIDFormat is the format of the id @@ -212,7 +212,7 @@ func (sp *ServiceProvider) Metadata() *EntityDescriptor { ValidUntil: &validUntil, }, SingleLogoutServices: sloEndpoints, - NameIDFormats: []NameIDFormat{sp.AuthnNameIDFormat}, + NameIDFormats: []NameIDFormat{"urn:oasis:names:tc:SAML:2.0:nameid-format:transient"}, }, AuthnRequestsSigned: &authnRequestsSigned, WantAssertionsSigned: &wantAssertionsSigned, diff --git a/service_provider_test.go b/service_provider_test.go index 4309738c..93a20960 100644 --- a/service_provider_test.go +++ b/service_provider_test.go @@ -21,7 +21,7 @@ import ( "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" - "github.com/crewjam/saml/testsaml" + "github.com/lorodoes/saml/testsaml" ) type ServiceProviderTest struct { diff --git a/user_attributes.go b/user_attributes.go new file mode 100644 index 00000000..9d924a4a --- /dev/null +++ b/user_attributes.go @@ -0,0 +1,3 @@ +package saml + +var UserAttributes = map[string]string{}