Home >Backend Development >Golang >GO authenticate access token (keycloak)

GO authenticate access token (keycloak)

王林
王林forward
2024-02-09 09:30:24798browse

GO 验证访问令牌(keycloak)

In modern network applications, security is crucial. In order to protect user data and system resources, verification of access tokens is an essential step. As a powerful identity authentication and access management solution, Keycloak provides developers with a simple and secure verification method. In this article, PHP editor Xigua will introduce how to use Keycloak to verify access tokens to ensure application security. With the guidance of this article, you will be able to easily implement access token verification and ensure that only authorized users can access your application.

Question content

I am trying to implement access token verification using GO. But the examples I've seen online seem to just use TOKEN_SECRET to validate it. But I'm used to programming in Java spring and don't need to use TOKEN_SECRET. I just provide the jwk-set-uri and it checks for validity (auto - security filters etc) and I know it talks to the oauth server and does this validation.

Is there no library in Go that can check if the token is valid by making a request to the oauth server?

I know I know I can do this manually by making a request to the oauth server's userinfo endpoint:

http://localhost:8080/auth/realms/<your_realm>/protocol/openid-connect/userinfo

(Include token in header with key authorization)

But I don't know if this fully meets the criteria.

What is the correct approach?

Solution

Short answer: Use go-oidc

Long answer: First, let’s understand how Spring Security automatically validates JWT access tokens. By convention, if you define OAuth 2.0 or OIDC client properties in the application.yaml configuration file, Spring will automatically wire up a filter in the security filter chain, getting jwk- set, Keycloak is a set of public keys corresponding to the keys Keycloak uses to sign tokens. The filter will be applied to all protected routes and spring will use the public key to check that the token's signature is valid and make other checks if applicable (audience, timeout, etc...)

So how do we do this in Go? We can write a simple middleware that accepts jwk-set and uses it to validate the token. You need to check the alg declaration to see which signature algorithm was used, select the corresponding public key from jwk-set and check that the signature is valid. Then, decode the token, confirm the iss and sub claims to ensure it comes from a trusted issuer and is intended for the intended audience, and check that it has not expired. Check that the times declared by nbf (not before) and iat (issued after) are correct. Finally, relevant information from the token is injected into the request context if needed downstream.

func JWTMiddleware(jwkSet map[string]*rsa.PublicKey) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            authHeader := r.Header.Get("Authorization")
            if authHeader == "" {
                http.Error(w, "Authorization header is required", http.StatusUnauthorized)
                return
            }

            tokenString := strings.TrimPrefix(authHeader, "Bearer ")
            token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
                if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
                    return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
                }

                alg := token.Method.Alg()
                publicKey, ok := jwkSet[alg]
                if !ok {
                    return nil, fmt.Errorf("no key found for signing method: %v", alg)
                }
                return publicKey, nil
            })
            
            if err != nil || !token.Valid {
                http.Error(w, "Invalid token", http.StatusUnauthorized)
                return
            }
            // Other checks, ISS, Aud, Expirey, etc ...
            // If needed, store the user principal 
            // and other relevant info the request context  
            next.ServeHTTP(w, r)
        })
    }
}

The above is the detailed content of GO authenticate access token (keycloak). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete
Previous article:Read csv into bytesNext article:Read csv into bytes