mirror of
https://github.com/grafana/grafana.git
synced 2024-12-26 17:01:09 -06:00
AzureAD OAuth: Add optional strict parsing of role_attribute_path for Azure AD (#42157)
* AzureAD OAuth: Add optional strict parsing of role_attribute_path for Azure AD Fix casting issues modify unit tests Unit test fix Add proper test args * Return empty role when using strict attribute mode * Raise error on empty role * Fix UT for latest case
This commit is contained in:
parent
ea7d5a6185
commit
6c468daabc
@ -508,6 +508,7 @@ auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
|
||||
token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
|
||||
allowed_domains =
|
||||
allowed_groups =
|
||||
role_attribute_strict = false
|
||||
|
||||
#################################### Okta OAuth #######################
|
||||
[auth.okta]
|
||||
|
@ -493,6 +493,7 @@
|
||||
;token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
|
||||
;allowed_domains =
|
||||
;allowed_groups =
|
||||
;role_attribute_strict = false
|
||||
|
||||
#################################### Okta OAuth #######################
|
||||
[auth.okta]
|
||||
|
@ -109,6 +109,7 @@ auth_url = https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/authorize
|
||||
token_url = https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token
|
||||
allowed_domains =
|
||||
allowed_groups =
|
||||
role_attribute_strict = false
|
||||
```
|
||||
|
||||
You can also use these environment variables to configure **client_id** and **client_secret**:
|
||||
|
@ -17,8 +17,9 @@ import (
|
||||
|
||||
type SocialAzureAD struct {
|
||||
*SocialBase
|
||||
allowedGroups []string
|
||||
autoAssignOrgRole string
|
||||
allowedGroups []string
|
||||
autoAssignOrgRole string
|
||||
roleAttributeStrict bool
|
||||
}
|
||||
|
||||
type azureClaims struct {
|
||||
@ -69,7 +70,10 @@ func (s *SocialAzureAD) UserInfo(client *http.Client, token *oauth2.Token) (*Bas
|
||||
return nil, errors.New("error getting user info: no email found in access token")
|
||||
}
|
||||
|
||||
role := extractRole(claims, s.autoAssignOrgRole)
|
||||
role := extractRole(claims, s.autoAssignOrgRole, s.roleAttributeStrict)
|
||||
if role == "" {
|
||||
return nil, errors.New("user does not have a valid role")
|
||||
}
|
||||
logger.Debug("AzureAD OAuth: extracted role", "email", email, "role", role)
|
||||
|
||||
groups, err := extractGroups(client, claims, token)
|
||||
@ -118,7 +122,7 @@ func extractEmail(claims azureClaims) string {
|
||||
return claims.Email
|
||||
}
|
||||
|
||||
func extractRole(claims azureClaims, autoAssignRole string) models.RoleType {
|
||||
func extractRole(claims azureClaims, autoAssignRole string, strictMode bool) models.RoleType {
|
||||
if len(claims.Roles) == 0 {
|
||||
return models.RoleType(autoAssignRole)
|
||||
}
|
||||
@ -135,6 +139,10 @@ func extractRole(claims azureClaims, autoAssignRole string) models.RoleType {
|
||||
}
|
||||
}
|
||||
|
||||
if strictMode {
|
||||
return models.RoleType("")
|
||||
}
|
||||
|
||||
return models.ROLE_VIEWER
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,10 @@ import (
|
||||
|
||||
func TestSocialAzureAD_UserInfo(t *testing.T) {
|
||||
type fields struct {
|
||||
SocialBase *SocialBase
|
||||
allowedGroups []string
|
||||
autoAssignOrgRole string
|
||||
SocialBase *SocialBase
|
||||
allowedGroups []string
|
||||
autoAssignOrgRole string
|
||||
roleAttributeStrict bool
|
||||
}
|
||||
type args struct {
|
||||
client *http.Client
|
||||
@ -279,13 +280,30 @@ func TestSocialAzureAD_UserInfo(t *testing.T) {
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Fetch empty role when strict attribute role is true and no match",
|
||||
fields: fields{
|
||||
roleAttributeStrict: true,
|
||||
},
|
||||
claims: &azureClaims{
|
||||
Email: "me@example.com",
|
||||
PreferredUsername: "",
|
||||
Roles: []string{"foo"},
|
||||
Groups: []string{},
|
||||
Name: "My Name",
|
||||
ID: "1234",
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := &SocialAzureAD{
|
||||
SocialBase: tt.fields.SocialBase,
|
||||
allowedGroups: tt.fields.allowedGroups,
|
||||
autoAssignOrgRole: tt.fields.autoAssignOrgRole,
|
||||
SocialBase: tt.fields.SocialBase,
|
||||
allowedGroups: tt.fields.allowedGroups,
|
||||
autoAssignOrgRole: tt.fields.autoAssignOrgRole,
|
||||
roleAttributeStrict: tt.fields.roleAttributeStrict,
|
||||
}
|
||||
|
||||
key := []byte("secret")
|
||||
|
@ -149,9 +149,10 @@ func ProvideService(cfg *setting.Cfg) *SocialService {
|
||||
// AzureAD.
|
||||
if name == "azuread" {
|
||||
ss.socialMap["azuread"] = &SocialAzureAD{
|
||||
SocialBase: newSocialBase(name, &config, info),
|
||||
allowedGroups: util.SplitString(sec.Key("allowed_groups").String()),
|
||||
autoAssignOrgRole: cfg.AutoAssignOrgRole,
|
||||
SocialBase: newSocialBase(name, &config, info),
|
||||
allowedGroups: util.SplitString(sec.Key("allowed_groups").String()),
|
||||
autoAssignOrgRole: cfg.AutoAssignOrgRole,
|
||||
roleAttributeStrict: info.RoleAttributeStrict,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user