forked from Gayadeed/spid-go
/
logoutrequest_out.go
108 lines (94 loc) · 2.93 KB
/
logoutrequest_out.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
package spidsaml
import (
"bytes"
"text/template"
)
// LogoutRequestOut defines an outgoing SPID/SAML LogoutRequest.
// You can use it to generate such a request in case you're initiating
// a logout procedure on behalf of your user.
// Do not instantiate it directly but use sp.NewLogoutRequest() instead.
type LogoutRequestOut struct {
outMessage
Session *Session
}
// NewLogoutRequest generates a LogoutRequest addressed to the Identity Provider.
// Note that this method does not perform any network call, it just initializes
// an object.
func (sp *SP) NewLogoutRequest(session *Session) (*LogoutRequestOut, error) {
req := new(LogoutRequestOut)
req.SP = sp
var err error
req.IDP, err = sp.GetIDP(session.IDPEntityID)
if err != nil {
return nil, err
}
req.ID = GenerateRandomID()
req.Session = session
return req, nil
}
// XML generates the XML representation of this LogoutRequest
func (logoutreq *LogoutRequestOut) XML(binding SAMLBinding) []byte {
var signatureTemplate string
if binding == HTTPPost {
signatureTemplate = string(logoutreq.signatureTemplate())
}
data := struct {
*LogoutRequestOut
Destination string
IssueInstant string
SignatureTemplate string
}{
logoutreq,
logoutreq.IDP.SLOReqURLs[binding],
logoutreq.IssueInstantString(),
signatureTemplate,
}
const tmpl = `<?xml version="1.0"?>
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="{{ .ID }}"
Version="2.0"
IssueInstant="{{ .IssueInstant }}"
Destination="{{ .Destination }}">
<saml:Issuer
NameQualifier="{{ .SP.EntityID }}"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
{{ .SP.EntityID }}
</saml:Issuer>
{{ .SignatureTemplate }}
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
NameQualifier="{{ .Session.IDPEntityID }}">
{{ .Session.NameID }}
</saml:NameID>
<samlp:SessionIndex>
{{ .Session.SessionIndex }}
</samlp:SessionIndex>
</samlp:LogoutRequest>
`
t := template.Must(template.New("req").Parse(tmpl))
var metadata bytes.Buffer
if t.Execute(&metadata, data) != nil {
return nil
}
return metadata.Bytes()
}
// RedirectURL returns the full URL of the Identity Provider where user should be
// redirected in order to initiate their Single Logout. In SAML words, this
// implements the HTTP-Redirect binding.
func (logoutreq *LogoutRequestOut) RedirectURL() string {
return logoutreq.outMessage.RedirectURL(
logoutreq.IDP.SLOReqURLs[HTTPRedirect],
logoutreq.XML(HTTPRedirect),
"SAMLRequest",
)
}
// PostForm returns an HTML page with a JavaScript auto-post command that submits
// the request to the Identity Provider in order to initiate their Single Logout.
// In SAML words, this implements the HTTP-POST binding.
func (logoutreq *LogoutRequestOut) PostForm() []byte {
return logoutreq.outMessage.PostForm(
logoutreq.IDP.SLOReqURLs[HTTPPost],
logoutreq.XML(HTTPPost),
"SAMLRequest",
)
}