-
Notifications
You must be signed in to change notification settings - Fork 0
/
samlauth.go
106 lines (93 loc) · 2.59 KB
/
samlauth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package main
import (
"context"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"fmt"
"net/http"
"net/url"
"time"
"github.com/CoPhi/cophi-auth-service/auth"
"github.com/CoPhi/cophi-auth-service/refreshtoken"
"github.com/crewjam/saml"
"github.com/crewjam/saml/samlsp"
)
func samlSPCallback(privKey, domain string, rts refreshtoken.Store, jwtExpiration time.Duration) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
user := auth.AuthUser{
Name: samlsp.AttributeFromContext(r.Context(), "givenName"),
LastName: samlsp.AttributeFromContext(r.Context(), "sn"),
Email: samlsp.AttributeFromContext(r.Context(), "mail"),
}
http.SetCookie(w, &http.Cookie{
Name: "token",
Value: "",
Path: "/",
MaxAge: -1,
HttpOnly: true,
})
referer, err := r.Cookie("referer")
if err != nil {
fmt.Fprintln(w, err)
return
}
auth.AuthCallback(referer.Value, rts, &user, privKey, domain, jwtExpiration)(w, r)
}
}
type safeSamlMiddleware struct {
certificate tls.Certificate
idpMetadataURL *url.URL
rootURL *url.URL
idpMetadata *saml.EntityDescriptor
samlSP *samlsp.Middleware
err error
}
func NewSP(cert, certKey, idpURL, rootURL string, ctx context.Context, httpClient *http.Client) (*samlsp.Middleware, error) {
m := safeSamlMiddleware{}
m.loadX509KeyPair(cert, certKey)
m.parseCertificate(m.certificate.Certificate[0])
m.parseMetadataURL(idpURL)
m.fetchMetadata(ctx, httpClient, *m.idpMetadataURL)
m.parseRootURL(rootURL)
if m.err != nil {
return nil, m.err
}
m.samlSP, m.err = samlsp.New(samlsp.Options{
URL: *m.rootURL,
Key: m.certificate.PrivateKey.(*rsa.PrivateKey),
Certificate: m.certificate.Leaf,
IDPMetadata: m.idpMetadata,
})
return m.samlSP, m.err
}
func (s *safeSamlMiddleware) fetchMetadata(ctx context.Context, httpClient *http.Client, metadataURL url.URL) {
if s.err != nil {
return
}
s.idpMetadata, s.err = samlsp.FetchMetadata(ctx, httpClient, metadataURL)
}
func (s *safeSamlMiddleware) loadX509KeyPair(cert, key string) {
if s.err != nil {
return
}
s.certificate, s.err = tls.X509KeyPair([]byte(cert), []byte(key))
}
func (s *safeSamlMiddleware) parseCertificate(der []byte) {
if s.err != nil {
return
}
s.certificate.Leaf, s.err = x509.ParseCertificate(der)
}
func (s *safeSamlMiddleware) parseMetadataURL(rawURL string) {
if s.err != nil {
return
}
s.idpMetadataURL, s.err = url.Parse(rawURL)
}
func (s *safeSamlMiddleware) parseRootURL(rawURL string) {
if s.err != nil {
return
}
s.rootURL, s.err = url.Parse(rawURL)
}