in pkg/provider/shibbolethecp/shibbolethecp.go [84:136]
func (c *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) {
// Step 1: Request resource from IdP, indicate we are ECP capable
ar, err := authnRequest(c.idpAccount.AlibabaCloudURN)
if err != nil {
return "", err
}
req, err := http.NewRequest("POST", loginDetails.URL, ar)
if err != nil {
return "", errors.Wrapf(err, "Error creating new http request for %s", loginDetails.URL)
}
req.Header.Set("Content-Type", "text/xml")
req.Header.Set("charset", "utf-8")
req.Header.Set(SHIB_DUO_FACTOR, c.idpAccount.MFA)
req.SetBasicAuth(loginDetails.Username, loginDetails.Password)
// if user chose passcode, then optionally prompt for the token and set the SHIB_DUO_PASSCODE header
if c.idpAccount.MFA == "passcode" {
if loginDetails.MFAToken == "" {
req.Header.Set(SHIB_DUO_PASSCODE, prompter.RequestSecurityCode("000000"))
} else {
req.Header.Set(SHIB_DUO_PASSCODE, loginDetails.MFAToken)
}
}
res, err := c.client.Do(req)
defer res.Body.Close()
if err != nil {
return "", errors.Wrap(err, "Sending initial SOAP authnRequest")
}
if res.StatusCode != 200 {
return "", errors.Wrapf(err, "Response code from IDP at %s: %s", res.Status, res.Request.URL)
}
bodyBytes, _ := ioutil.ReadAll(res.Body)
logger.Debugf("IDP Response: %s", bodyBytes)
res.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) // reset
// Step 2: Process the returned <AuthnRequest>
// check for SAML_SUCCESS in S:Body/saml2p:Response/saml2p:Status/saml2p:StatusCode/@Value
assertion, err := extractAssertion(res.Body)
logger.Debugf("err = %s", err)
if err != nil {
return "", err
}
logger.Debugf("SAML Assertion: %s", assertion)
// saml2alibabacloud expects the assertion to be base64 encoded
return base64.StdEncoding.EncodeToString([]byte(assertion)), nil
}