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