mirror of
https://github.com/grafana/grafana.git
synced 2025-01-14 02:32:29 -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
|
token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
|
||||||
allowed_domains =
|
allowed_domains =
|
||||||
allowed_groups =
|
allowed_groups =
|
||||||
|
role_attribute_strict = false
|
||||||
|
|
||||||
#################################### Okta OAuth #######################
|
#################################### Okta OAuth #######################
|
||||||
[auth.okta]
|
[auth.okta]
|
||||||
|
@ -493,6 +493,7 @@
|
|||||||
;token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
|
;token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
|
||||||
;allowed_domains =
|
;allowed_domains =
|
||||||
;allowed_groups =
|
;allowed_groups =
|
||||||
|
;role_attribute_strict = false
|
||||||
|
|
||||||
#################################### Okta OAuth #######################
|
#################################### Okta OAuth #######################
|
||||||
[auth.okta]
|
[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
|
token_url = https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token
|
||||||
allowed_domains =
|
allowed_domains =
|
||||||
allowed_groups =
|
allowed_groups =
|
||||||
|
role_attribute_strict = false
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also use these environment variables to configure **client_id** and **client_secret**:
|
You can also use these environment variables to configure **client_id** and **client_secret**:
|
||||||
|
@ -17,8 +17,9 @@ import (
|
|||||||
|
|
||||||
type SocialAzureAD struct {
|
type SocialAzureAD struct {
|
||||||
*SocialBase
|
*SocialBase
|
||||||
allowedGroups []string
|
allowedGroups []string
|
||||||
autoAssignOrgRole string
|
autoAssignOrgRole string
|
||||||
|
roleAttributeStrict bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type azureClaims struct {
|
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")
|
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)
|
logger.Debug("AzureAD OAuth: extracted role", "email", email, "role", role)
|
||||||
|
|
||||||
groups, err := extractGroups(client, claims, token)
|
groups, err := extractGroups(client, claims, token)
|
||||||
@ -118,7 +122,7 @@ func extractEmail(claims azureClaims) string {
|
|||||||
return claims.Email
|
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 {
|
if len(claims.Roles) == 0 {
|
||||||
return models.RoleType(autoAssignRole)
|
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
|
return models.ROLE_VIEWER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,10 @@ import (
|
|||||||
|
|
||||||
func TestSocialAzureAD_UserInfo(t *testing.T) {
|
func TestSocialAzureAD_UserInfo(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
SocialBase *SocialBase
|
SocialBase *SocialBase
|
||||||
allowedGroups []string
|
allowedGroups []string
|
||||||
autoAssignOrgRole string
|
autoAssignOrgRole string
|
||||||
|
roleAttributeStrict bool
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
@ -279,13 +280,30 @@ func TestSocialAzureAD_UserInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
wantErr: false,
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
s := &SocialAzureAD{
|
s := &SocialAzureAD{
|
||||||
SocialBase: tt.fields.SocialBase,
|
SocialBase: tt.fields.SocialBase,
|
||||||
allowedGroups: tt.fields.allowedGroups,
|
allowedGroups: tt.fields.allowedGroups,
|
||||||
autoAssignOrgRole: tt.fields.autoAssignOrgRole,
|
autoAssignOrgRole: tt.fields.autoAssignOrgRole,
|
||||||
|
roleAttributeStrict: tt.fields.roleAttributeStrict,
|
||||||
}
|
}
|
||||||
|
|
||||||
key := []byte("secret")
|
key := []byte("secret")
|
||||||
|
@ -149,9 +149,10 @@ func ProvideService(cfg *setting.Cfg) *SocialService {
|
|||||||
// AzureAD.
|
// AzureAD.
|
||||||
if name == "azuread" {
|
if name == "azuread" {
|
||||||
ss.socialMap["azuread"] = &SocialAzureAD{
|
ss.socialMap["azuread"] = &SocialAzureAD{
|
||||||
SocialBase: newSocialBase(name, &config, info),
|
SocialBase: newSocialBase(name, &config, info),
|
||||||
allowedGroups: util.SplitString(sec.Key("allowed_groups").String()),
|
allowedGroups: util.SplitString(sec.Key("allowed_groups").String()),
|
||||||
autoAssignOrgRole: cfg.AutoAssignOrgRole,
|
autoAssignOrgRole: cfg.AutoAssignOrgRole,
|
||||||
|
roleAttributeStrict: info.RoleAttributeStrict,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user