# Connecting with Go

This guide explains how to establish a connection between a Go application and a Keycloak identity provider using the OIDC (OpenID Connect) protocol. It walks through the necessary setup, configuration, and execution of a basic login flow to authenticate users through Keycloak.

## **Variables**

Certain parameters must be provided to integrate a Go application with Keycloak. Below is a breakdown of each required variable, its purpose, and where to find it. Here’s what each variable represents:

<table border="1" id="bkmrk-variable-description" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Variable**

</th><th style="border-color: rgb(0, 0, 0);">**Description**

</th><th style="border-color: rgb(0, 0, 0);">**Purpose**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);">`CLIENT_ID`

</td><td style="border-color: rgb(0, 0, 0);">Client ID from the Keycloak Admin Console

</td><td style="border-color: rgb(0, 0, 0);">Identifies the Go app in the Keycloak realm

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">`CLIENT_SECRET`

</td><td style="border-color: rgb(0, 0, 0);">Secret from the Credentials tab of the client

</td><td style="border-color: rgb(0, 0, 0);">Authenticates the Go app with Keycloak

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">`ISSUER_URL`

</td><td style="border-color: rgb(0, 0, 0);"><span class="s1">Realm URL (e.g., </span>https://your-domain/realms/your-realm<span class="s1">)</span>

</td><td style="border-color: rgb(0, 0, 0);">Base URL for OIDC discovery and validation

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">`REDIRECT_URL`

</td><td style="border-color: rgb(0, 0, 0);">The callback URL Keycloak redirects to after successful login

</td><td style="border-color: rgb(0, 0, 0);">Required to complete the OIDC flow

</td></tr></tbody></table>

These values are found under <span class="s1">**Clients &gt; \[Your Client\] &gt; Settings / Endpoints**</span> in the Keycloak Admin Console.

## **Prerequisites**

##### **Install Go**

Check if Go is installed:

```
go version
```

If not installed, download it from [https://golang.org/dl](https://golang.org/dl) and install.

##### **Install Required Packages**

Install the required Go packages:

```
go get github.com/coreos/go-oidc/v3
go get golang.org/x/oauth2
```

## **Code**

Once all prerequisites are set up, create a new file named <span class="s2">main.go</span> and add the following code:

```go
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/clientcredentials"
	"golang.org/x/oauth2/endpoints"
	"github.com/coreos/go-oidc/v3/oidc"
)

var (
	clientID     = "CLIENT_ID"
	clientSecret = "CLIENT_SECRET"
	redirectURL  = "http://localhost:8080/callback"
	issuerURL    = "https://your-keycloak-domain/realms/your-realm"
)

func main() {
	ctx := context.Background()

	provider, err := oidc.NewProvider(ctx, issuerURL)
	if err != nil {
		log.Fatalf("Failed to get provider: %v", err)
	}

	verifier := provider.Verifier(&oidc.Config{ClientID: clientID})

	config := oauth2.Config{
		ClientID:     clientID,
		ClientSecret: clientSecret,
		Endpoint:     provider.Endpoint(),
		Scopes:       []string{oidc.ScopeOpenID, "profile", "email"},
		RedirectURL:  redirectURL,
	}

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		url := config.AuthCodeURL("state", oauth2.AccessTypeOffline)
		http.Redirect(w, r, url, http.StatusFound)
	})

	http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		if r.URL.Query().Get("state") != "state" {
			http.Error(w, "state mismatch", http.StatusBadRequest)
			return
		}

		oauth2Token, err := config.Exchange(ctx, r.URL.Query().Get("code"))
		if err != nil {
			http.Error(w, "failed to exchange token: "+err.Error(), http.StatusInternalServerError)
			return
		}

		rawIDToken, ok := oauth2Token.Extra("id_token").(string)
		if !ok {
			http.Error(w, "no id_token field in oauth2 token", http.StatusInternalServerError)
			return
		}

		idToken, err := verifier.Verify(ctx, rawIDToken)
		if err != nil {
			http.Error(w, "failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
			return
		}

		var claims map[string]interface{}
		if err := idToken.Claims(&claims); err != nil {
			http.Error(w, "failed to parse claims: "+err.Error(), http.StatusInternalServerError)
			return
		}

		fmt.Fprintf(w, "Login successful! User info:\n\n%v", claims)
	})

	log.Println("Server started at http://localhost:8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}
```

Replace:

- <span class="s1">CLIENT\_ID</span> and <span class="s1">CLIENT\_SECRET</span> with your Keycloak client credentials
- https://your-keycloak-domain/realms/your-realm<span class="s1"> with your realm’s base URL</span>
- <span class="s1">http://localhost:8080/callback</span> should be registered in Keycloak’s <span class="s2">**Valid Redirect URIs**</span>

## **Execute**

1. Run the application with:

```
go run main.go
```

2. In your browser, navigate to:

```
http://localhost:8080
```

3. You will be redirected to the Keycloak login screen. After logging in:

- The app will redirect to <span class="s1">/callback</span>
- If successful, you’ll see your decoded user info printed on the screen