-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
137 lines (109 loc) · 4.06 KB
/
main.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
131
132
133
134
135
136
137
package main
import (
"fmt"
"log"
"net/http"
"github.com/RobotsAndPencils/go-saml"
"github.com/gorilla/mux"
)
import "text/template"
var sp = saml.ServiceProviderSettings{
PublicCertPath: "frntn-x509-san.crt",
PrivateKeyPath: "frntn-x509-san.key",
IDPSSOURL: "http://192.168.244.160:8080/sso",
IDPSSODescriptorURL: "http://192.168.244.160:8080/issuer",
IDPPublicCertPath: "frntn-x509-san.crt", //Private key to sign and pusblic key to verify. The reason for IdP providing you its certificate is for SP to validate the signed SAML responses sent by the IdP.
SPSignRequest: true,
AssertionConsumerServiceURL: "http://192.168.244.160:8000/acs", //Destination on Response, will check against this
}
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/", Index)
router.HandleFunc("/login", Login)
router.HandleFunc("/acs", ACS).Methods("POST")
log.Fatal(http.ListenAndServe(":8000", router))
}
func Index(w http.ResponseWriter, r *http.Request) {
fmt.Println("This is the SSOClient")
}
func ACS(w http.ResponseWriter, r *http.Request) {
encodedXML := r.FormValue("SAMLResponse")
//WTF is httpcommon
//fmt.Println("ACS Hit", encodedXML)
if encodedXML == "" {
//httpcommon.SendBadRequest(w, "SAMLResponse form value missing")
w.WriteHeader(500)
w.Write([]byte("SAMLResponse form value missing"))
return
}
response, err := saml.ParseEncodedResponse(encodedXML)
if err != nil {
//httpcommon.SendBadRequest(w, "SAMLResponse parse: "+err.Error())
w.WriteHeader(500)
w.Write([]byte("SAMLResponse parse: " + err.Error()))
return
}
// fmt.Println("Response", response)
err = response.Validate(&sp) //publicCertPath is sp
if err != nil {
//httpcommon.SendBadRequest(w, "SAMLResponse validation: "+err.Error())
w.WriteHeader(500)
w.Write([]byte("SAMLResponse validation: " + err.Error()))
return
}
samlID := response.GetAttribute("email")
if samlID == "" {
//httpcommon.SendBadRequest(w, "SAML attribute identifier uid missing")
w.Write([]byte("SAML attribute identifier uid missing"))
return
}
w.Write([]byte("Hello " + samlID))
//...
}
//Login user with IdP
func Login(w http.ResponseWriter, r *http.Request) {
sp.Init()
// generate the AuthnRequest and then get a base64 encoded string of the XML
authnRequest := sp.GetAuthnRequest()
b64XML, err := authnRequest.EncodedSignedString(sp.PrivateKeyPath)
if err != nil {
panic(err)
}
// for convenience, get a URL formed with the SAMLRequest parameter
//The third aparameter the relay state
relaystate := ""
url, err := saml.GetAuthnRequestURL(sp.IDPSSOURL, b64XML, relaystate)
if err != nil {
panic(err)
}
// below is bonus for how you might respond to a request with a form that POSTs to the IdP
data := struct {
Base64AuthRequest string
URL string
}{
Base64AuthRequest: b64XML,
URL: url,
}
t := template.New("saml")
t, err = t.Parse("<html><body style=\"display: none\" onload=\"document.frm.submit()\"><form method=\"post\" name=\"frm\" action=\"{{.URL}}\"><input type=\"hidden\" name=\"SAMLRequest\" value=\"{{.Base64AuthRequest}}\" /><input type=\"submit\" value=\"Submit\" /></form></body></html>")
// how you might respond to a request with the templated form that will auto post
t.Execute(w, data)
}
//The Service Provider (SP) receives metadata from the Identity Provider (IdP),
//parses it and sends back SP Metadata XML to the IdP.
//Metadata can be either generated automatically upon first request to the
//service, or it can be pre-created (see Chapter 11, Sample application). Once
//created metadata needs to be provided to the identity providers with whom we
//want to establish trust.
func samlMetadataHandler(sp *saml.ServiceProviderSettings) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
md, err := sp.GetEntityDescriptor()
if err != nil {
w.WriteHeader(500)
w.Write([]byte("Error: " + err.Error()))
return
}
w.Header().Set("Content-Type", "application/xml")
w.Write([]byte(md))
})
}