forked from gravitational/teleport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
saml.go
119 lines (108 loc) · 3.74 KB
/
saml.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
package web
import (
"net/http"
"net/url"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/httplib"
"github.com/gravitational/teleport/lib/services"
log "github.com/Sirupsen/logrus"
"github.com/gravitational/form"
"github.com/gravitational/trace"
"github.com/julienschmidt/httprouter"
)
func (m *Handler) samlSSO(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) {
log.Debugf("samlSSO start")
query := r.URL.Query()
clientRedirectURL := query.Get("redirect_url")
if clientRedirectURL == "" {
return nil, trace.BadParameter("missing redirect_url query parameter")
}
connectorID := query.Get("connector_id")
if connectorID == "" {
return nil, trace.BadParameter("missing connector_id query parameter")
}
response, err := m.cfg.ProxyClient.CreateSAMLAuthRequest(
services.SAMLAuthRequest{
ConnectorID: connectorID,
CreateWebSession: true,
ClientRedirectURL: clientRedirectURL,
})
if err != nil {
return nil, trace.Wrap(err)
}
http.Redirect(w, r, response.RedirectURL, http.StatusFound)
return nil, nil
}
func (m *Handler) samlSSOConsole(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) {
log.Debugf("samlSSOConsole start")
var req *client.SSOLoginConsoleReq
if err := httplib.ReadJSON(r, &req); err != nil {
return nil, trace.Wrap(err)
}
if req.RedirectURL == "" {
return nil, trace.BadParameter("missing RedirectURL")
}
if len(req.PublicKey) == 0 {
return nil, trace.BadParameter("missing PublicKey")
}
if req.ConnectorID == "" {
return nil, trace.BadParameter("missing ConnectorID")
}
response, err := m.cfg.ProxyClient.CreateSAMLAuthRequest(
services.SAMLAuthRequest{
ConnectorID: req.ConnectorID,
ClientRedirectURL: req.RedirectURL,
PublicKey: req.PublicKey,
CertTTL: req.CertTTL,
Compatibility: req.Compatibility,
})
if err != nil {
return nil, trace.Wrap(err)
}
return &client.SSOLoginConsoleResponse{RedirectURL: response.RedirectURL}, nil
}
func (m *Handler) samlACS(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) {
var samlResponse string
err := form.Parse(r, form.String("SAMLResponse", &samlResponse, form.Required()))
if err != nil {
return nil, trace.Wrap(err)
}
l := log.WithFields(log.Fields{trace.Component: "SAML"})
response, err := m.cfg.ProxyClient.ValidateSAMLResponse(samlResponse)
if err != nil {
log.Warningf("error while processing callback: %v", err)
// redirect to an error page
pathToError := url.URL{
Path: "/web/msg/error/login_failed",
RawQuery: url.Values{"details": []string{"Unable to process callback from OIDC provider."}}.Encode(),
}
http.Redirect(w, r, pathToError.String(), http.StatusFound)
return nil, nil
}
// if we created web session, set session cookie and redirect to original url
if response.Req.CreateWebSession {
log.Debugf("redirecting to web browser")
if err := SetSession(w, response.Username, response.Session.GetName()); err != nil {
return nil, trace.Wrap(err)
}
http.Redirect(w, r, response.Req.ClientRedirectURL, http.StatusFound)
return nil, nil
}
l.Debugf("samlCallback redirecting to console login")
if len(response.Req.PublicKey) == 0 {
return nil, trace.BadParameter("not a web or console oidc login request")
}
redirectURL, err := ConstructSSHResponse(AuthParams{
ClientRedirectURL: response.Req.ClientRedirectURL,
Username: response.Username,
Identity: response.Identity,
Session: response.Session,
Cert: response.Cert,
HostSigners: response.HostSigners,
})
if err != nil {
return nil, trace.Wrap(err)
}
http.Redirect(w, r, redirectURL.String(), http.StatusFound)
return nil, nil
}