英文:
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"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论