diff --git a/controllers/auth.go b/controllers/auth.go index a4e9dbf3..84e5baf5 100644 --- a/controllers/auth.go +++ b/controllers/auth.go @@ -103,12 +103,12 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob resp = tokenToResponse(token) } } else if form.Type == ResponseTypeSaml { // saml flow - res, redirectUrl, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host) + res, redirectUrl, method, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host) if err != nil { c.ResponseError(err.Error(), nil) return } - resp = &Response{Status: "ok", Msg: "", Data: res, Data2: redirectUrl} + resp = &Response{Status: "ok", Msg: "", Data: res, Data2: map[string]string{"redirectUrl": redirectUrl, "method": method}} } else if form.Type == ResponseTypeCas { // not oauth but CAS SSO protocol service := c.Input().Get("service") diff --git a/object/saml_idp.go b/object/saml_idp.go index 92598f3c..696bea48 100644 --- a/object/saml_idp.go +++ b/object/saml_idp.go @@ -223,11 +223,14 @@ func GetSamlMeta(application *Application, host string) (*IdpEntityDescriptor, e // GetSamlResponse generates a SAML2.0 response // parameter samlRequest is saml request in base64 format -func GetSamlResponse(application *Application, user *User, samlRequest string, host string) (string, string, error) { +func GetSamlResponse(application *Application, user *User, samlRequest string, host string) (string, string, string, error) { + // request type + method := "GET" + // base64 decode defated, err := base64.StdEncoding.DecodeString(samlRequest) if err != nil { - return "", "", fmt.Errorf("err: %s", err.Error()) + return "", "", method, fmt.Errorf("err: %s", err.Error()) } // decompress var buffer bytes.Buffer @@ -236,12 +239,12 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h var authnRequest saml.AuthnRequest err = xml.Unmarshal(buffer.Bytes(), &authnRequest) if err != nil { - return "", "", fmt.Errorf("err: %s", err.Error()) + return "", "", method, fmt.Errorf("err: %s", err.Error()) } // verify samlRequest if isValid := application.IsRedirectUriValid(authnRequest.Issuer.Url); !isValid { - return "", "", fmt.Errorf("err: Issuer URI: %s doesn't exist in the allowed Redirect URI list", authnRequest.Issuer.Url) + return "", "", method, fmt.Errorf("err: Issuer URI: %s doesn't exist in the allowed Redirect URI list", authnRequest.Issuer.Url) } // get certificate string @@ -253,6 +256,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h // redirect Url (Assertion Consumer Url) if application.SamlReplyUrl != "" { + method = "POST" authnRequest.AssertionConsumerServiceURL = application.SamlReplyUrl } @@ -275,7 +279,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h doc.SetRoot(samlResponse) xmlBytes, err := doc.WriteToBytes() if err != nil { - return "", "", fmt.Errorf("err: %s", err.Error()) + return "", "", method, fmt.Errorf("err: %s", err.Error()) } // compress @@ -283,7 +287,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h flated := bytes.NewBuffer(nil) writer, err := flate.NewWriter(flated, flate.DefaultCompression) if err != nil { - return "", "", fmt.Errorf("err: %s", err.Error()) + return "", "", method, fmt.Errorf("err: %s", err.Error()) } writer.Write(xmlBytes) writer.Close() @@ -291,7 +295,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h } // base64 encode res := base64.StdEncoding.EncodeToString(xmlBytes) - return res, authnRequest.AssertionConsumerServiceURL, nil + return res, authnRequest.AssertionConsumerServiceURL, method, nil } // NewSamlResponse11 return a saml1.1 response(not 2.0) diff --git a/web/src/auth/AuthCallback.js b/web/src/auth/AuthCallback.js index c7962c9f..428ca231 100644 --- a/web/src/auth/AuthCallback.js +++ b/web/src/auth/AuthCallback.js @@ -20,6 +20,7 @@ import * as Util from "./Util"; import {authConfig} from "./Auth"; import * as Setting from "../Setting"; import i18next from "i18next"; +import RedirectForm from "../common/RedirectForm"; class AuthCallback extends React.Component { constructor(props) { @@ -27,6 +28,9 @@ class AuthCallback extends React.Component { this.state = { classes: props, msg: null, + samlResponse: "", + relayState: "", + redirectUrl: "", }; } @@ -164,9 +168,17 @@ class AuthCallback extends React.Component { const from = innerParams.get("from"); Setting.goToLinkSoft(this, from); } else if (responseType === "saml") { - const SAMLResponse = res.data; - const redirectUri = res.data2; - Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`); + if (res.data2.method === "POST") { + this.setState({ + samlResponse: res.data, + redirectUrl: res.data2.redirectUrl, + relayState: oAuthParams.relayState, + }); + } else { + const SAMLResponse = res.data; + const redirectUri = res.data2.redirectUrl; + Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`); + } } } else { this.setState({ @@ -177,6 +189,10 @@ class AuthCallback extends React.Component { } render() { + if (this.state.samlResponse !== "") { + return ; + } + return (
{ diff --git a/web/src/auth/LoginPage.js b/web/src/auth/LoginPage.js index 530bf9cd..0053dbca 100644 --- a/web/src/auth/LoginPage.js +++ b/web/src/auth/LoginPage.js @@ -320,15 +320,15 @@ class LoginPage extends React.Component { const accessToken = res.data; Setting.goToLink(`${oAuthParams.redirectUri}#${responseType}=${accessToken}?state=${oAuthParams.state}&token_type=bearer`); } else if (responseType === "saml") { - const SAMLResponse = res.data; - const redirectUri = res.data2; - if (this.state.application.assertionConsumerUrl !== "") { + if (res.data2.method === "POST") { this.setState({ samlResponse: res.data, - redirectUrl: res.data2, + redirectUrl: res.data2.redirectUrl, relayState: oAuthParams.relayState, }); } else { + const SAMLResponse = res.data; + const redirectUri = res.data2.redirectUrl; Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`); } } @@ -616,13 +616,13 @@ class LoginPage extends React.Component { this.sendSilentSigninData("signing-in"); const values = {}; - values["application"] = this.state.application.name; + values["application"] = application.name; this.onFinish(values); } if (application.enableAutoSignin) { const values = {}; - values["application"] = this.state.application.name; + values["application"] = application.name; this.onFinish(values); } @@ -637,7 +637,7 @@ class LoginPage extends React.Component {
{ const values = {}; - values["application"] = this.state.application.name; + values["application"] = application.name; this.onFinish(values); }} />