[auth] make id-token optional (#97831)
make idtoken optional enure there is always an identity in the context fix: update token fix: now it should work fix: now it should work
This commit is contained in:
@@ -5,20 +5,15 @@ import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/fullstorydev/grpchan"
|
||||
"github.com/fullstorydev/grpchan/inprocgrpc"
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v3/jwt"
|
||||
authnlib "github.com/grafana/authlib/authn"
|
||||
"github.com/grafana/authlib/claims"
|
||||
grpcAuth "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
"github.com/grafana/grafana/pkg/services/authn/grpcutils"
|
||||
grpcUtils "github.com/grafana/grafana/pkg/storage/unified/resource/grpc"
|
||||
)
|
||||
@@ -139,19 +134,7 @@ func idTokenExtractor(ctx context.Context) (string, error) {
|
||||
return token[0], nil
|
||||
}
|
||||
|
||||
// If no token is found, create an internal token.
|
||||
// This is a workaround for StaticRequester not having a signed ID token.
|
||||
if staticRequester, ok := authInfo.(*identity.StaticRequester); ok {
|
||||
token, _, err := createInternalToken(staticRequester)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create internal token: %w", err)
|
||||
}
|
||||
|
||||
staticRequester.IDToken = token
|
||||
return token, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("id-token not found")
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func allowInsecureTransportOpt(grpcClientConfig *authnlib.GrpcClientConfig, opts []authnlib.GrpcClientInterceptorOption) []authnlib.GrpcClientInterceptorOption {
|
||||
@@ -159,45 +142,3 @@ func allowInsecureTransportOpt(grpcClientConfig *authnlib.GrpcClientConfig, opts
|
||||
tokenClient, _ := authnlib.NewTokenExchangeClient(*grpcClientConfig.TokenClientConfig, authnlib.WithHTTPClient(client))
|
||||
return append(opts, authnlib.WithTokenClientOption(tokenClient))
|
||||
}
|
||||
|
||||
// createInternalToken creates a symmetrically signed token for using in in-proc mode only.
|
||||
func createInternalToken(authInfo claims.AuthInfo) (string, *authnlib.Claims[authnlib.IDTokenClaims], error) {
|
||||
signerOpts := jose.SignerOptions{}
|
||||
signerOpts.WithType("jwt") // Should be uppercase, but this is what authlib expects
|
||||
signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: []byte("internal key")}, &signerOpts)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
tokenTTL := 10 * time.Minute
|
||||
idClaims := &auth.IDClaims{
|
||||
Claims: jwt.Claims{
|
||||
Audience: authInfo.GetAudience(),
|
||||
Subject: authInfo.GetSubject(),
|
||||
Expiry: jwt.NewNumericDate(now.Add(tokenTTL)),
|
||||
IssuedAt: jwt.NewNumericDate(now),
|
||||
},
|
||||
Rest: authnlib.IDTokenClaims{
|
||||
Namespace: authInfo.GetNamespace(),
|
||||
Identifier: authInfo.GetIdentifier(),
|
||||
Type: authInfo.GetIdentityType(),
|
||||
},
|
||||
}
|
||||
|
||||
if claims.IsIdentityType(authInfo.GetIdentityType(), claims.TypeUser) {
|
||||
idClaims.Rest.Email = authInfo.GetEmail()
|
||||
idClaims.Rest.EmailVerified = authInfo.GetEmailVerified()
|
||||
idClaims.Rest.AuthenticatedBy = authInfo.GetAuthenticatedBy()
|
||||
idClaims.Rest.Username = authInfo.GetUsername()
|
||||
idClaims.Rest.DisplayName = authInfo.GetName()
|
||||
}
|
||||
|
||||
builder := jwt.Signed(signer).Claims(&idClaims.Rest).Claims(idClaims.Claims)
|
||||
token, err := builder.CompactSerialize()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return token, idClaims, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIDTokenExtractor(t *testing.T) {
|
||||
t.Run("should return an error when no claims found", func(t *testing.T) {
|
||||
token, err := idTokenExtractor(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, token)
|
||||
})
|
||||
t.Run("should return an empty token for static requester of type service account as grafana admin ", func(t *testing.T) {
|
||||
ctx := identity.WithRequester(context.Background(), &identity.StaticRequester{
|
||||
Type: claims.TypeServiceAccount,
|
||||
IsGrafanaAdmin: true,
|
||||
})
|
||||
token, err := idTokenExtractor(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, token)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user