forked from Calpicow/go-saml
/
settings.go
130 lines (110 loc) · 3.24 KB
/
settings.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package saml
import (
"encoding/base64"
"encoding/pem"
"io/ioutil"
)
//Settings to configure saml properties for
//one idp and/or one sp.
//If you need to configure multipe IDPs for an SP
//then configure multiple instances of this object
type Settings struct {
SP ServiceProviderSettings
IDP IdentityProviderSettings
Compress CompressionSettings
hasInit bool
}
//CompressionSettings to determine if requests and responses should be compressed
type CompressionSettings struct {
Request bool
Response bool
}
//ServiceProviderSettings provides settings to configure server acting as a SAML Service Provider.
//Expect only one IDP per SP in this configuration.
type ServiceProviderSettings struct {
EntityID string
PublicCertPath string
PublicCertString string
PrivateKeyPath string
PrivateKeyString string
AssertionConsumerServiceURL string
SingleLogoutServiceURL string
SignRequest bool
IsPassive bool
publicCert *pem.Block
privateKey *pem.Block
}
//IdentityProviderSettings to configure idp specific settings
type IdentityProviderSettings struct {
SingleLogoutURL string
SingleSignOnURL string
SingleSignOnDescriptorURL string
PublicCertPath string
PublicCertString string
NameIDFormat string
publicCert *pem.Block
}
//Init settings and load configuration files as needed
//This will panic on error as SP/IDP fails to load
func (s *Settings) Init() (err error) {
if s.hasInit {
return nil
}
s.hasInit = true
if s.SP.SignRequest {
s.SP.privateKey = s.loadPEM("SP-Pivate Key", s.SP.PrivateKeyString, s.SP.PrivateKeyPath)
s.SP.publicCert = s.loadPEM("SP-Public Cert", s.SP.PublicCertString, s.SP.PublicCertPath)
s.IDP.publicCert = s.loadPEM("IDP-Public Cert", s.IDP.PublicCertString, s.IDP.PublicCertPath)
} else {
s.SP.privateKey = &pem.Block{}
s.SP.publicCert = &pem.Block{}
s.SP.publicCert = &pem.Block{}
}
//Set the sp entity id to acs url if not found for
//backwards compatibility with old configuration
if s.SP.EntityID == "" && s.SP.AssertionConsumerServiceURL != "" {
s.SP.EntityID = s.SP.AssertionConsumerServiceURL
}
return nil
}
func (s *Settings) loadPEM(pemType string, pemString string, pemPath string) *pem.Block {
var block *pem.Block
if pemString != "" {
block, _ = pem.Decode([]byte(pemString))
} else {
block = readPEMFile(pemPath)
}
if block == nil {
panic("Unable to load PEM: " + pemType)
}
return block
}
func readPEMFile(path string) *pem.Block {
bytes, err := ioutil.ReadFile(path)
if err != nil {
panic(err)
}
block, _ := pem.Decode(bytes)
return block
}
//SPPublicCert get loaded sp public certificate data
func (s *Settings) SPPublicCert() string {
if !s.hasInit {
s.Init()
}
return base64.StdEncoding.EncodeToString(s.SP.publicCert.Bytes)
}
//SPPrivateKey get loaded sp private key in pem format
func (s *Settings) SPPrivateKey() string {
if !s.hasInit {
s.Init()
}
return string(pem.EncodeToMemory(s.SP.privateKey))
}
//IDPPublicCert get loaded idp public certificate in pem format
func (s *Settings) IDPPublicCert() string {
if !s.hasInit {
s.Init()
}
return string(pem.EncodeToMemory(s.IDP.publicCert))
}