func()

in pkg/provider/shibboleth/shibboleth.go [50:118]


func (sc *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) {

	var authSubmitURL string
	var samlAssertion string

	shibbolethURL := fmt.Sprintf("%s/idp/profile/SAML2/Unsolicited/SSO?providerId=%s", loginDetails.URL, sc.idpAccount.AlibabaCloudURN)

	res, err := sc.client.Get(shibbolethURL)
	if err != nil {
		return samlAssertion, errors.Wrap(err, "error retrieving form")
	}

	doc, err := goquery.NewDocumentFromResponse(res)
	if err != nil {
		return samlAssertion, errors.Wrap(err, "failed to build document from response")
	}

	authForm := url.Values{}

	doc.Find("input").Each(func(i int, s *goquery.Selection) {
		updateFormData(authForm, s, loginDetails)
	})

	doc.Find("form").Each(func(i int, s *goquery.Selection) {
		action, ok := s.Attr("action")
		if !ok {
			return
		}
		authSubmitURL = action
	})

	if authSubmitURL == "" {
		return samlAssertion, fmt.Errorf("unable to locate IDP authentication form submit URL")
	}

	req, err := http.NewRequest("POST", authSubmitURL, strings.NewReader(authForm.Encode()))
	if err != nil {
		return samlAssertion, errors.Wrap(err, "error building authentication request")
	}

	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	req.URL.Host = res.Request.URL.Host
	req.URL.Scheme = res.Request.URL.Scheme

	res, err = sc.client.Do(req)
	if err != nil {
		return samlAssertion, errors.Wrap(err, "error retrieving login form results")
	}

	switch sc.idpAccount.MFA {
	case "Auto":
		b, _ := ioutil.ReadAll(res.Body)

		mfaRes, err := verifyMfa(sc, loginDetails.URL, string(b))
		if err != nil {
			return mfaRes.Status, errors.Wrap(err, "error verifying MFA")
		}

		res = mfaRes

	}

	samlAssertion, err = extractSamlResponse(res)
	if err != nil {
		return samlAssertion, errors.Wrap(err, "error extracting SAMLResponse blob from final Shibboleth response")
	}

	return samlAssertion, nil
}