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

huangapple go评论85阅读模式
英文:

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

问题

我正在编写一个API,用于在Keycloak服务器中创建一个新的客户端。我使用gocloak包与Keycloak服务器进行交互。起初,我将gocloak.Login()函数返回的访问令牌传递给gocloak.CreateClient(),但是在此之后,我收到了403错误。然后我改用gocloak.LoginAdmin()返回的访问令牌,它成功了,成功创建了一个新的客户端。那么是什么导致了gocloak.Login()返回的访问令牌失败?

代码:

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)

	}

}

结果:

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

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

答案1

得分: 2

要使用Keycloak Admin API,其中包括创建客户端的功能,您需要使用admin-cli客户端。

这就是为什么使用以下代码可以正常工作:

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

因为LoginAdmin调用了admin-cli,而以下代码:

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

是请求来自客户端"my-go-service"的令牌,该客户端不被允许调用Admin Rest API。因此会返回403 Forbidden: unknown_error。

如果您查看LoginAdmin的实现,您可以确认我所说的:

// 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,
    })
}

其中

adminClientID string = "admin-cli"
英文:

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"

huangapple
  • 本文由 发表于 2022年6月19日 23:13:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/72678031.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定