mirror of https://github.com/grafana/grafana
AuthN: New service to support multiple authentication providers for plugins (#75979)
* OnGoing * Continue migrating structure * Comment * Add intermediary service * Remove unused error so far * no need for fmt use errors * use RoleNone * Docs * Fix test * Accounting for review feedback * Rename oauthserver.ExternalService to OAuthClient * Revert as the interface looks weird * Update pluginintegration * Rename oauthserver.ExternalService * closer to what it was beforepull/78145/head
parent
03baf210b3
commit
e902d8fd10
@ -0,0 +1,7 @@ |
||||
package extsvcauth |
||||
|
||||
import "github.com/grafana/grafana/pkg/util/errutil" |
||||
|
||||
var ( |
||||
ErrUnknownProvider = errutil.BadRequest("extsvcauth.unknown-provider") |
||||
) |
@ -1 +0,0 @@ |
||||
package extsvcauth |
@ -0,0 +1,91 @@ |
||||
package extsvcauth |
||||
|
||||
import ( |
||||
"context" |
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol" |
||||
) |
||||
|
||||
const ( |
||||
OAuth2Server AuthProvider = "OAuth2Server" |
||||
) |
||||
|
||||
type AuthProvider string |
||||
|
||||
type ExternalServiceRegistry interface { |
||||
// SaveExternalService creates or updates an external service in the database. Based on the requested auth provider,
|
||||
// it generates client_id, secrets and any additional provider specificities (ex: rsa keys). It also ensures that the
|
||||
// associated service account has the correct permissions.
|
||||
SaveExternalService(ctx context.Context, cmd *ExternalServiceRegistration) (*ExternalService, error) |
||||
} |
||||
|
||||
type SelfCfg struct { |
||||
// Enabled allows the service to request access tokens for itself
|
||||
Enabled bool |
||||
// Permissions are the permissions that the external service needs its associated service account to have.
|
||||
Permissions []accesscontrol.Permission |
||||
} |
||||
|
||||
type ImpersonationCfg struct { |
||||
// Enabled allows the service to request access tokens to impersonate users
|
||||
Enabled bool |
||||
// Groups allows the service to list the impersonated user's teams
|
||||
Groups bool |
||||
// Permissions are the permissions that the external service needs when impersonating a user.
|
||||
// The intersection of this set with the impersonated user's permission guarantees that the client will not
|
||||
// gain more privileges than the impersonated user has and vice versa.
|
||||
Permissions []accesscontrol.Permission |
||||
} |
||||
|
||||
// ExternalServiceRegistration represents the registration form to save new client.
|
||||
type ExternalServiceRegistration struct { |
||||
Name string |
||||
// Impersonation access configuration
|
||||
// (this is not available on all auth providers)
|
||||
Impersonation ImpersonationCfg |
||||
// Self access configuration
|
||||
Self SelfCfg |
||||
// Auth Provider that the client will use to connect to Grafana
|
||||
AuthProvider AuthProvider |
||||
// Auth Provider specific config
|
||||
OAuthProviderCfg *OAuthProviderCfg |
||||
} |
||||
|
||||
// ExternalService represents the credentials that the ExternalService can use to connect to Grafana.
|
||||
type ExternalService struct { |
||||
Name string |
||||
ID string |
||||
Secret string |
||||
OAuthExtra *OAuthExtra // Auth Provider specificities (ex: ecdsa key pair)
|
||||
} |
||||
|
||||
type KeyOption struct { |
||||
// URL string `json:"url,omitempty"` // TODO allow specifying a URL (to a .jwks file) to fetch the key from
|
||||
// PublicPEM contains the Base64 encoded public key in PEM format
|
||||
PublicPEM string |
||||
Generate bool |
||||
} |
||||
|
||||
// ProviderCfg represents the registration form specificities needed to register OAuth2 clients.
|
||||
type OAuthProviderCfg struct { |
||||
// RedirectURI is the URI that is used in the code flow.
|
||||
// Note that this is not used yet.
|
||||
RedirectURI *string |
||||
// Key is the option to specify a public key or ask the server to generate a crypto key pair.
|
||||
Key *KeyOption |
||||
} |
||||
|
||||
type KeyResult struct { |
||||
URL string |
||||
PrivatePem string |
||||
PublicPem string |
||||
Generated bool |
||||
} |
||||
|
||||
// OAuthExtra represents the specificities of an OAuth2 client.
|
||||
type OAuthExtra struct { |
||||
Audiences string |
||||
GrantTypes string |
||||
KeyResult *KeyResult |
||||
RedirectURI string |
||||
} |
@ -0,0 +1,43 @@ |
||||
package registry |
||||
|
||||
import ( |
||||
"context" |
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log" |
||||
"github.com/grafana/grafana/pkg/services/extsvcauth" |
||||
"github.com/grafana/grafana/pkg/services/extsvcauth/oauthserver" |
||||
"github.com/grafana/grafana/pkg/services/featuremgmt" |
||||
) |
||||
|
||||
var _ extsvcauth.ExternalServiceRegistry = &Registry{} |
||||
|
||||
type Registry struct { |
||||
features featuremgmt.FeatureToggles |
||||
logger log.Logger |
||||
oauthServer oauthserver.OAuth2Server |
||||
} |
||||
|
||||
func ProvideExtSvcRegistry(oauthServer oauthserver.OAuth2Server, features featuremgmt.FeatureToggles) *Registry { |
||||
return &Registry{ |
||||
features: features, |
||||
logger: log.New("extsvcauth.registry"), |
||||
oauthServer: oauthServer, |
||||
} |
||||
} |
||||
|
||||
// SaveExternalService creates or updates an external service in the database. Based on the requested auth provider,
|
||||
// it generates client_id, secrets and any additional provider specificities (ex: rsa keys). It also ensures that the
|
||||
// associated service account has the correct permissions.
|
||||
func (r *Registry) SaveExternalService(ctx context.Context, cmd *extsvcauth.ExternalServiceRegistration) (*extsvcauth.ExternalService, error) { |
||||
switch cmd.AuthProvider { |
||||
case extsvcauth.OAuth2Server: |
||||
if !r.features.IsEnabled(featuremgmt.FlagExternalServiceAuth) { |
||||
r.logger.Warn("Skipping external service authentication, flag disabled", "service", cmd.Name, "flag", featuremgmt.FlagExternalServiceAuth) |
||||
return nil, nil |
||||
} |
||||
r.logger.Debug("Routing the External Service registration to the OAuth2Server", "service", cmd.Name) |
||||
return r.oauthServer.SaveExternalService(ctx, cmd) |
||||
default: |
||||
return nil, extsvcauth.ErrUnknownProvider.Errorf("unknow provider '%v'", cmd.AuthProvider) |
||||
} |
||||
} |
Loading…
Reference in new issue