mirror of https://github.com/grafana/grafana
[authn] use authlib client+interceptors for in-proc mode (#93124)
* Add authlib gRPC authenticators for in-proc mode * implement `StaticRequester` signing in the unified resource client - [x] when the `claims.AuthInfo` value type is `identity.StaticRequester`, and there's no ID token set, create an internal token and sign it with symmetrical key. This is a workaround for `go-jose` not offering the possibility to create an unsigned token. - [x] update `IDClaimsWrapper` to support the scenario above - [x] Switch to using `claims.From()` in `dashboardSqlAccess.SaveDashboard()` --------- Co-authored-by: gamab <gabriel.mabille@grafana.com>pull/93642/head
parent
db97da3465
commit
a8b07b0c81
@ -0,0 +1,54 @@ |
||||
package idtest |
||||
|
||||
import ( |
||||
"time" |
||||
|
||||
"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" |
||||
|
||||
"github.com/grafana/grafana/pkg/services/auth" |
||||
) |
||||
|
||||
func CreateInternalToken(authInfo claims.AuthInfo, secret []byte) (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: secret}, &signerOpts) |
||||
if err != nil { |
||||
return "", nil, err |
||||
} |
||||
|
||||
identity := authInfo.GetIdentity() |
||||
now := time.Now() |
||||
tokenTTL := 10 * time.Minute |
||||
idClaims := &auth.IDClaims{ |
||||
Claims: &jwt.Claims{ |
||||
Audience: identity.Audience(), |
||||
Subject: identity.Subject(), |
||||
Expiry: jwt.NewNumericDate(now.Add(tokenTTL)), |
||||
IssuedAt: jwt.NewNumericDate(now), |
||||
}, |
||||
Rest: authnlib.IDTokenClaims{ |
||||
Namespace: identity.Namespace(), |
||||
Identifier: identity.Identifier(), |
||||
Type: identity.IdentityType(), |
||||
}, |
||||
} |
||||
|
||||
if claims.IsIdentityType(identity.IdentityType(), claims.TypeUser) { |
||||
idClaims.Rest.Email = identity.Email() |
||||
idClaims.Rest.EmailVerified = identity.EmailVerified() |
||||
idClaims.Rest.AuthenticatedBy = identity.AuthenticatedBy() |
||||
idClaims.Rest.Username = identity.Username() |
||||
idClaims.Rest.DisplayName = identity.DisplayName() |
||||
} |
||||
|
||||
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,14 @@ |
||||
package grpcutils |
||||
|
||||
import ( |
||||
authnlib "github.com/grafana/authlib/authn" |
||||
) |
||||
|
||||
func NewInProcGrpcAuthenticator() *authnlib.GrpcAuthenticator { |
||||
// In proc grpc ID token signature verification can be skipped
|
||||
return authnlib.NewUnsafeGrpcAuthenticator( |
||||
&authnlib.GrpcAuthenticatorConfig{}, |
||||
authnlib.WithDisableAccessTokenAuthOption(), |
||||
authnlib.WithIDTokenAuthOption(true), |
||||
) |
||||
} |
Loading…
Reference in new issue