github.com/versent/saml2aws@v2.17.0+incompatible/pkg/provider/adfs2/adfs2.go (about)

     1  package adfs2
     2  
     3  import (
     4  	"crypto/tls"
     5  	"log"
     6  	"net/http"
     7  	"net/http/cookiejar"
     8  
     9  	"golang.org/x/net/publicsuffix"
    10  
    11  	"github.com/Azure/go-ntlmssp"
    12  	"github.com/PuerkitoBio/goquery"
    13  	"github.com/sirupsen/logrus"
    14  	"github.com/versent/saml2aws/pkg/cfg"
    15  	"github.com/versent/saml2aws/pkg/creds"
    16  )
    17  
    18  var logger = logrus.WithField("provider", "adfs2")
    19  
    20  // Client client for adfs2
    21  type Client struct {
    22  	idpAccount *cfg.IDPAccount
    23  	client     *http.Client
    24  }
    25  
    26  // New new adfs2 client with ntlmssp configured
    27  func New(idpAccount *cfg.IDPAccount) (*Client, error) {
    28  	transport := &ntlmssp.Negotiator{
    29  		RoundTripper: &http.Transport{
    30  			Proxy:           http.ProxyFromEnvironment,
    31  			TLSClientConfig: &tls.Config{InsecureSkipVerify: idpAccount.SkipVerify, Renegotiation: tls.RenegotiateFreelyAsClient},
    32  		},
    33  	}
    34  
    35  	jar, err := cookiejar.New(&cookiejar.Options{
    36  		PublicSuffixList: publicsuffix.List,
    37  	})
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	client := &http.Client{
    43  		Transport: transport,
    44  		Jar:       jar,
    45  	}
    46  
    47  	return &Client{
    48  		client:     client,
    49  		idpAccount: idpAccount,
    50  	}, nil
    51  }
    52  
    53  // Authenticate authenticate the user using the supplied login details
    54  func (ac *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) {
    55  	switch ac.idpAccount.MFA {
    56  	case "RSA":
    57  		return ac.authenticateRsa(loginDetails)
    58  	default:
    59  		return ac.authenticateNTLM(loginDetails) // this is chosen as the default to maintain compatibility with existing users
    60  	}
    61  }
    62  
    63  func extractSamlAssertion(doc *goquery.Document) (string, error) {
    64  	var samlAssertion string
    65  
    66  	doc.Find("input").Each(func(i int, s *goquery.Selection) {
    67  		name, ok := s.Attr("name")
    68  		if !ok {
    69  			log.Fatalf("unable to locate IDP authentication form submit URL")
    70  		}
    71  		if name == "SAMLResponse" {
    72  			val, ok := s.Attr("value")
    73  			if !ok {
    74  				log.Fatalf("unable to locate saml assertion value")
    75  			}
    76  			samlAssertion = val
    77  		}
    78  	})
    79  
    80  	return samlAssertion, nil
    81  }