DEV Community

Cover image for SAML SSO Implementation in Golang: A Comprehensive Step-by-Step Guide
Andrew for SSOJet

Posted on • Originally published at ssojet.com

SAML SSO Implementation in Golang: A Comprehensive Step-by-Step Guide

Introduction

The Security Assertion Markup Language (SAML) is a widely recognized standard protocol that enables secure authentication and authorization between two distinct systems. SAML provides a secure means for exchanging information between two parties, eliminating the need to store user credentials in multiple locations. SAML is extensively used in enterprise environments to facilitate a Single Sign-On (SSO) solution for various applications. This article aims to guide you through implementing SAML in Golang by providing a sample code to assist you in getting started. We will cover all the essential aspects of SAML implementation in Golang that you need to know to get started. Let’s get started

Step 1: Install the necessary packages

You need to install the following packages using the go get command for SAML implementation in GoLang:

go get -u github.com/crewjam/saml github.com/crewjam/saml/samlsp
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a SAML Service Provider

Create a SAML Service Provider (SP) to receive and process SAML responses from the Identity Provider (IdP) using the samlsp.Middleware struct:

sp, err := samlsp.New(samlsp.Options{
    IDPMetadataURL: "https://idp.example.com/metadata",
    SAMLNameIDFormat: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
    RelayState: "https://app.example.com/after-auth",
    PrivateKeyFile: "sp-key.pem",
    CertificateFile: "sp-cert.pem",
})

http.HandleFunc("/saml/acs", func(w http.ResponseWriter, r *http.Request) {
    err := sp.ServeHTTP(w, r)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    http.Redirect(w, r, sp.DefaultRedirectURI(), http.StatusFound)
})

log.Fatal(http.ListenAndServe(":8080", nil))
Enter fullscreen mode Exit fullscreen mode

Step 3: Create a SAML Identity Provider

To create a SAML Identity Provider (IdP), use the saml.IdentityProvider struct:

keyPair, _ := tls.LoadX509KeyPair("idp-cert.pem", "idp-key.pem")
idp := &saml.IdentityProvider{
    Key:         keyPair.PrivateKey,
    Certificate: keyPair.Certificate,
    IDPMetadata: &saml.EntityDescriptor{
        ID:    "_12345",
        EntityID: "https://idp.example.com/metadata",
        RoleDescriptors: []saml.RoleDescriptor{
            &saml.IDPSSODescriptor{
                ProtocolSupportEnumeration: []string{
                    "urn:oasis:names:tc:SAML:2.0:protocol",
                },
                KeyDescriptors: []saml.KeyDescriptor{
                    &saml.KeyDescriptor{
                        Use: "signing",
                        KeyInfo: &ds.KeyInfo{
                            X509Datas: []ds.X509Data{
                                ds.X509Data{
                                    X509Certificates: []ds.X509Certificate{
                                        ds.X509Certificate{
                                            Data: certData,
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
                SingleLogoutServices: []saml.Endpoint{
                    saml.Endpoint{
                        Binding:  saml.HTTPRedirectBinding,
                        Location: "https://idp.example.com/sls",
                    },
                },
                NameIDFormats: []string{
                    "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
                },
                SingleSignOnServices: []saml.Endpoint{
                    saml.Endpoint{
                        Binding:  saml.HTTPRedirectBinding,
                        Location: "https://idp.example.com/sso",
                    },
                },
            },
        },
    },
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Generate a SAML AuthnRequest

To generate a SAML AuthnRequest, use the samlsp.AuthRequest function:

authnRequest, err := sp.MakeAuthRedirect(r.Context(), saml.IDPSSOBindingPOST)
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

http.Redirect(w, r, authnRequest, http.StatusFound)
Enter fullscreen mode Exit fullscreen mode

Step 5: Process the SAML Response

To process the SAML response, use the sp.ServeHTTP method:

err := sp.ServeHTTP(w, r)
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

http.Redirect(w, r, sp.DefaultRedirectURI(), http.StatusFound)
Enter fullscreen mode Exit fullscreen mode

And that’s it! You have successfully implemented SAML in Golang.

Conclusion

To sum up, we have furnished a detailed guide on implementing SAML in Golang, along with a sample code to assist you in commencing the process. SAML implementation in Golang offers a secure means of authentication and authorization between two distinct systems.

SAML is a commonly utilized protocol in enterprise settings, providing a Single Sign-On (SSO) resolution for multiple applications. This guide can assist you in implementing SAML in Golang without difficulty, enhancing the security of your web applications.

If you have any queries or suggestions, please let us know at support@ssojet.com. We would be happy to help you!

Top comments (0)