Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/RobotsAndPencils/go-saml
A just good enough SAML client library written in Go.
https://github.com/RobotsAndPencils/go-saml
Last synced: 28 days ago
JSON representation
A just good enough SAML client library written in Go.
- Host: GitHub
- URL: https://github.com/RobotsAndPencils/go-saml
- Owner: RobotsAndPencils
- License: mit
- Archived: true
- Created: 2015-07-27T16:43:59.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2023-11-15T19:43:36.000Z (about 1 year ago)
- Last Synced: 2024-05-18T15:40:03.433Z (7 months ago)
- Language: Go
- Size: 32.2 KB
- Stars: 132
- Watchers: 14
- Forks: 82
- Open Issues: 24
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-saml - RobotsAndPencils/go-saml
- awesome - go-saml - A just good enough SAML client library written in Go. (Go)
README
## Unsupported
Unfortunately, the decision has been made to sunset support for this project. We thank everyone for supporting and utilizing the project.
Couple of alternatives could be https://github.com/russellhaering/gosaml2 or maybe https://github.com/crewjam/saml. These are solely suggestions to start the look for an alternative and are not an endorsement by RNP. We've not done a code review of these repos. We recommend doing a vetting pass on the repository prior to integrating any third party dependencies.
go-saml
======[![Build Status](https://travis-ci.org/RobotsAndPencils/go-saml.svg?branch=master)](https://travis-ci.org/RobotsAndPencils/go-saml)
A just good enough SAML client library written in Go. This library is by no means complete and has been developed
to solve several specific integration efforts. However, it's a start, and it would be great to see
it evolve into a more fleshed out implemention.Inspired by the early work of [Matt Baird](https://github.com/mattbaird/gosaml).
The library supports:
* generating signed/unsigned AuthnRequests
* validating signed AuthnRequests
* generating service provider metadata
* generating signed Responses
* validating signed ResponsesInstallation
------------$ go get github.com/RobotsAndPencils/go-saml
Here's a convenient way to generate a certificate:
curl -sSL https://raw.githubusercontent.com/frntn/x509-san/master/gencert.sh | CRT_CN="mycert" bash
Usage
-----Below are samples to show how you might use the library.
### Generating Signed AuthnRequests
```go
sp := saml.ServiceProviderSettings{
PublicCertPath: "../default.crt",
PrivateKeyPath: "../default.key",
IDPSSOURL: "http://idp/saml2",
IDPSSODescriptorURL: "http://idp/issuer",
IDPPublicCertPath: "idpcert.crt",
SPSignRequest: "true",
AssertionConsumerServiceURL: "http://localhost:8000/saml_consume",
}
sp.Init()// generate the AuthnRequest and then get a base64 encoded string of the XML
authnRequest := sp.GetAuthnRequest()
b64XML, err := authnRequest.EncodedSignedString(sp.PrivateKeyPath)
if err != nil {
panic(err)
}// for convenience, get a URL formed with the SAMLRequest parameter
url, err := saml.GetAuthnRequestURL(sp.IDPSSOURL, b64XML)
if err != nil {
panic(err)
}// below is bonus for how you might respond to a request with a form that POSTs to the IdP
data := struct {
Base64AuthRequest string
URL string
}{
Base64AuthRequest: b64XML,
URL: url,
}t := template.New("saml")
t, err = t.Parse("")// how you might respond to a request with the templated form that will auto post
t.Execute(w, data)
```### Validating a received SAML Response
```go
response = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
encodedXML := r.FormValue("SAMLResponse")if encodedXML == "" {
httpcommon.SendBadRequest(w, "SAMLResponse form value missing")
return
}response, err := saml.ParseEncodedResponse(encodedXML)
if err != nil {
httpcommon.SendBadRequest(w, "SAMLResponse parse: "+err.Error())
return
}err = response.Validate(&sp)
if err != nil {
httpcommon.SendBadRequest(w, "SAMLResponse validation: "+err.Error())
return
}samlID := response.GetAttribute("uid")
if samlID == "" {
httpcommon.SendBadRequest(w, "SAML attribute identifier uid missing")
return
}//...
}
```### Service provider metadata
```go
func samlMetadataHandler(sp *saml.ServiceProviderSettings) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
md, err := sp.GetEntityDescriptor()
if err != nil {
w.WriteHeader(500)
w.Write([]byte("Error: " + err.Error()))
return
}w.Header().Set("Content-Type", "application/xml")
w.Write([]byte(md))
})
}
```### Receiving a authnRequest
```go
b64Request := r.URL.Query().Get("SAMLRequest")
if b64Request == "" {
w.WriteHeader(400)
w.Write([]byte("SAMLRequest parameter missing"))
return
}defated, err := base64.StdEncoding.DecodeString(b64Request)
if err != nil {
w.WriteHeader(500)
w.Write([]byte("Error: " + err.Error()))
return
}// enflate and unmarshal
var buffer bytes.Buffer
rdr := flate.NewReader(bytes.NewReader(defated))
io.Copy(&buffer, rdr)
var authnRequest saml.AuthnRequesterr = xml.Unmarshal(buffer.Bytes(), &authnRequest)
if err != nil {
w.WriteHeader(500)
w.Write([]byte("Error: " + err.Error()))
return
}if authnRequest.Issuer.Url != issuerURL {
w.WriteHeader(500)
w.Write([]byte("unauthorized issuer "+authnRequest.Issuer.Url))
return
}```
### Creating a SAML Response (if acting as an IdP)
```go
issuer := "http://localhost:8000/saml"
authnResponse := saml.NewSignedResponse()
authnResponse.Issuer.Url = issuer
authnResponse.Assertion.Issuer.Url = issuer
authnResponse.Signature.KeyInfo.X509Data.X509Certificate.Cert = stringValueOfCert
authnResponse.Assertion.Subject.NameID.Value = userIdThatYouAuthenticated
authnResponse.AddAttribute("uid", userIdThatYouAuthenticated)
authnResponse.AddAttribute("email", "someone@domain")
authnResponse.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.InResponseTo = authnRequestIdRespondingTo
authnResponse.InResponseTo = authnRequestIdRespondingTo
authnResponse.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.Recipient = issuer// signed XML string
signed, err := authnResponse.SignedString("/path/to/private.key")// or signed base64 encoded XML string
b64XML, err := authnResponse.EncodedSignedString("/path/to/private.key")```
### Contributing
Would love any contributions you having including better documentation, tests, or more robust functionality.
git clone [email protected]:RobotsAndPencils/go-saml.git
make init
make test### Contact
[![Robots & Pencils Logo](http://f.cl.ly/items/2W3n1r2R0j2p2b3n3j3c/rnplogo.png)](http://www.robotsandpencils.com)
Made with :heart: by Robots & Pencils ([@robotsNpencils](https://twitter.com/robotsNpencils))
#### Maintainers
- [Mike Brevoort](http://github.com/mbrevoort) ([@mbrevoort](https://twitter.com/mbrevoort))