Why i can't create a new client in KeyCloak with access token from Login() in gocloak?

Issue

I’m writing an API that creates a new client in a keycloak server. I use the gocloak package to interact with the keycloak server. At first i passed in the access token from the gocloak.Login() func to the gocloak.CreateClient() and got a 403 error after that i used the access token from gocloak.LoginAdmin() and it worked, it did create a new client. So what makes the access token returned from gocloak.Login() failed ?

Code:

func main() {

    newClientID := "new_client"

    client := gocloak.NewClient("http://localhost:8080")

    // The access token returned from Login() causes 403 error
    jwt, _ := client.Login(context.Background(), "my-go-service", "vizhhp0qnDGaiq4k0aOzzn4RaaqSwU2b", "master", "admin", "Pa55w0rd")
    _, err := client.CreateClient(context.Background(), jwt.AccessToken, "demorealm", gocloak.Client{ ClientID: &newClientID})

    if err != nil {
        fmt.Println(err.Error())
    }

    // And the access token returned from LoginAdmin() works
    jwt, _ = client.LoginAdmin(context.Background(), "admin", "Pa55w0rd", "master")
    clientID, err := client.CreateClient(context.Background(), jwt.AccessToken, "demorealm", gocloak.Client{ ClientID: &newClientID})

    if err != nil {
        fmt.Println(err.Error())
    } else {
        fmt.Printf("Client %s created", clientID)

    }

}

Result:

403 Forbidden: unknown_error
Client d869fd8d-e5f0-4567-99de-69ccc4403705 created

Solution

To use the Keycloak Admin API, which among others allows the creation of clients, you need to use the admin-cli client.

That is why with:

jwt, _ = client.LoginAdmin(context.Background(), "admin", "Pa55w0rd", "master")

works because LoginAdmin calls the admin-cli, whereas:

jwt, _ := client.Login(context.Background(), "my-go-service", "vizhhp0qnDGaiq4k0aOzzn4RaaqSwU2b", "master", "admin", "Pa55w0rd")

is requesting a token from client "my-go-service", which is not allowed to perform calls to the Admin Rest API. Hence:

403 Forbidden: unknown_error

If you look at the LoginAdmin implementation you can confirm what I have said:

// LoginAdmin performs a login with Admin client
func (client *gocloak) LoginAdmin(ctx context.Context, username, password, realm string) (*JWT, error) {
    return client.GetToken(ctx, realm, TokenOptions{
        ClientID:  StringP(adminClientID),
        GrantType: StringP("password"),
        Username:  &username,
        Password:  &password,
    })
}

where

adminClientID string = "admin-cli"

Answered By – dreamcrash

Answer Checked By – Jay B. (GoLangFix Admin)

Leave a Reply

Your email address will not be published.