-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update GitLab IDP to support OIDC #19997
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package gitlab | ||
|
||
import ( | ||
"net/http" | ||
"net/url" | ||
"strings" | ||
|
||
"github.com/openshift/origin/pkg/oauthserver/oauth/external" | ||
|
||
"github.com/golang/glog" | ||
) | ||
|
||
// The hosted version of GitLab is guaranteed to be using the latest stable version | ||
// meaning that we can count on it having OIDC support (and no sub claim bug) | ||
const gitlabHostedDomain = "gitlab.com" | ||
|
||
func NewProvider(providerName, URL, clientID, clientSecret string, transport http.RoundTripper, legacy *bool) (external.Provider, error) { | ||
if isLegacy(legacy, URL) { | ||
glog.Infof("Using legacy OAuth2 for GitLab identity provider %s url=%s clientID=%s", providerName, URL, clientID) | ||
return NewOAuthProvider(providerName, URL, clientID, clientSecret, transport) | ||
} | ||
glog.Infof("Using OIDC for GitLab identity provider %s url=%s clientID=%s", providerName, URL, clientID) | ||
return NewOIDCProvider(providerName, URL, clientID, clientSecret, transport) | ||
} | ||
|
||
func isLegacy(legacy *bool, URL string) bool { | ||
// if a value is specified, honor it | ||
if legacy != nil { | ||
return *legacy | ||
} | ||
|
||
// use OIDC if we know it will work since the hosted version is being used | ||
// validation handles URL parsing errors so we can ignore them here | ||
if u, err := url.Parse(URL); err == nil && strings.EqualFold(u.Hostname(), gitlabHostedDomain) { | ||
return false | ||
} | ||
|
||
// otherwise use OAuth2 (to be safe for now) | ||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package gitlab | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"path" | ||
"regexp" | ||
"strconv" | ||
|
||
"github.com/openshift/origin/pkg/oauthserver/oauth/external" | ||
"github.com/openshift/origin/pkg/oauthserver/oauth/external/openid" | ||
) | ||
|
||
const ( | ||
// https://gitlab.com/help/integration/openid_connect_provider.md | ||
// Uses GitLab OIDC, requires GitLab 11.1.0 or higher | ||
// Earlier versions do not work: https://gitlab.com/gitlab-org/gitlab-ce/issues/47791#note_81269161 | ||
gitlabAuthorizePath = "/oauth/authorize" | ||
gitlabTokenPath = "/oauth/token" | ||
gitlabUserInfoPath = "/oauth/userinfo" | ||
|
||
// https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/locales/doorkeeper.en.yml | ||
// Authenticate using OpenID Connect | ||
// The ability to authenticate using GitLab, and read-only access to the user's profile information and group memberships | ||
gitlabOIDCScope = "openid" | ||
|
||
// The ID of the user | ||
// See above comment about GitLab 11.1.0 and the custom IDTokenValidator below | ||
// Along with providerName, builds the identity object's Name field (see Identity.ProviderUserName) | ||
gitlabIDClaim = "sub" | ||
// The user's GitLab username | ||
// Used as the Name field of the user object (stored in Identity.Extra, see IdentityPreferredUsernameKey) | ||
gitlabPreferredUsernameClaim = "nickname" | ||
// The user's public email address | ||
// The value can optionally be used during manual provisioning (stored in Identity.Extra, see IdentityEmailKey) | ||
gitlabEmailClaim = "email" | ||
// The user's full name | ||
// Used as the FullName field of the user object (stored in Identity.Extra, see IdentityDisplayNameKey) | ||
gitlabDisplayNameClaim = "name" | ||
) | ||
|
||
func NewOIDCProvider(providerName, URL, clientID, clientSecret string, transport http.RoundTripper) (external.Provider, error) { | ||
// Create service URLs | ||
u, err := url.Parse(URL) | ||
if err != nil { | ||
return nil, fmt.Errorf("gitlab host URL %q is invalid", URL) | ||
} | ||
|
||
config := openid.Config{ | ||
ClientID: clientID, | ||
ClientSecret: clientSecret, | ||
|
||
AuthorizeURL: appendPath(*u, gitlabAuthorizePath), | ||
TokenURL: appendPath(*u, gitlabTokenPath), | ||
UserInfoURL: appendPath(*u, gitlabUserInfoPath), | ||
|
||
Scopes: []string{gitlabOIDCScope}, | ||
|
||
IDClaims: []string{gitlabIDClaim}, | ||
PreferredUsernameClaims: []string{gitlabPreferredUsernameClaim}, | ||
EmailClaims: []string{gitlabEmailClaim}, | ||
NameClaims: []string{gitlabDisplayNameClaim}, | ||
|
||
// make sure that gitlabIDClaim is a valid uint64, see above comment about GitLab 11.1.0 | ||
IDTokenValidator: func(idTokenClaims map[string]interface{}) error { | ||
gitlabID, ok := idTokenClaims[gitlabIDClaim].(string) | ||
if !ok { | ||
return nil // this is an OIDC spec violation which is handled by the default code path | ||
} | ||
if reSHA256HexDigest.MatchString(gitlabID) { | ||
return fmt.Errorf("incompatible gitlab IDP, ID claim is SHA256 hex digest instead of digit, claims=%#v", idTokenClaims) | ||
} | ||
if !isValidUint64(gitlabID) { | ||
return fmt.Errorf("invalid gitlab IDP, ID claim is not a digit, claims=%#v", idTokenClaims) | ||
} | ||
return nil | ||
}, | ||
} | ||
|
||
return openid.NewProvider(providerName, transport, config) | ||
} | ||
|
||
func appendPath(u url.URL, subpath string) string { | ||
u.Path = path.Join(u.Path, subpath) | ||
return u.String() | ||
} | ||
|
||
// Have 256 bits from hex digest | ||
// In hexadecimal each digit encodes 4 bits | ||
// Thus we need 64 digits to represent 256 bits | ||
var reSHA256HexDigest = regexp.MustCompile(`^[[:xdigit:]]{64}$`) | ||
|
||
func isValidUint64(s string) bool { | ||
_, err := strconv.ParseUint(s, 10, 64) | ||
return err == nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a good reason to prepend all these module variables with "gitlab" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Matches the existing code and the other provider integrations.