summaryrefslogtreecommitdiffstats
path: root/models/login_source.go
diff options
context:
space:
mode:
authorQuaSoft <info@quasoft.net>2019-11-23 01:33:31 +0200
committerLauris BH <lauris@nix.lv>2019-11-23 01:33:31 +0200
commit7b4d2f7a2aa3af093571628f979bdc939f10890c (patch)
treef9abd74c01d006892f5474557cb545e4f60dfe71 /models/login_source.go
parenteb1b225d9a920e68ce415b9732b4ec1d9527a2a2 (diff)
downloadgitea-7b4d2f7a2aa3af093571628f979bdc939f10890c.tar.gz
gitea-7b4d2f7a2aa3af093571628f979bdc939f10890c.zip
Add single sign-on support via SSPI on Windows (#8463)
* Add single sign-on support via SSPI on Windows * Ensure plugins implement interface * Ensure plugins implement interface * Move functions used only by the SSPI auth method to sspi_windows.go * Field SSPISeparatorReplacement of AuthenticationForm should not be required via binding, as binding will insist the field is non-empty even if another login type is selected * Fix breaking of oauth authentication on download links. Do not create new session with SSPI authentication on download links. * Update documentation for the new 'SPNEGO with SSPI' login source * Mention in documentation that ROOT_URL should contain the FQDN of the server * Make sure that Contexter is not checking for active login sources when the ORM engine is not initialized (eg. when installing) * Always initialize and free SSO methods, even if they are not enabled, as a method can be activated while the app is running (from Authentication sources) * Add option in SSPIConfig for removing of domains from logon names * Update helper text for StripDomainNames option * Make sure handleSignIn() is called after a new user object is created by SSPI auth method * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Remove default value from text of form field helper Co-Authored-By: Lauris BH <lauris@nix.lv> * Only make a query to the DB to check if SSPI is enabled on handlers that need that information for templates * Remove code duplication * Log errors in ActiveLoginSources Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert suffix of randomly generated E-mails for Reverse proxy authentication Co-Authored-By: Lauris BH <lauris@nix.lv> * Revert unneeded white-space change in template Co-Authored-By: Lauris BH <lauris@nix.lv> * Add copyright comments at the top of new files * Use loopback name for randomly generated emails * Add locale tag for the SSPISeparatorReplacement field with proper casing * Revert casing of SSPISeparatorReplacement field in locale file, moving it up, next to other form fields * Update docs/content/doc/features/authentication.en-us.md Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Remove Priority() method and define the order in which SSO auth methods should be executed in one place * Log authenticated username only if it's not empty * Rephrase helper text for automatic creation of users * Return error if more than one active SSPI auth source is found * Change newUser() function to return error, letting caller log/handle the error * Move isPublicResource, isPublicPage and handleSignIn functions outside SSPI auth method to allow other SSO methods to reuse them if needed * Refactor initialization of the list containing SSO auth methods * Validate SSPI settings on POST * Change SSPI to only perform authentication on its own login page, API paths and download links. Leave Toggle middleware to redirect non authenticated users to login page * Make 'Default language' in SSPI config empty, unless changed by admin * Show error if admin tries to add a second authentication source of type SSPI * Simplify declaration of global variable * Rebuild gitgraph.js on Linux * Make sure config values containing only whitespace are not accepted
Diffstat (limited to 'models/login_source.go')
-rw-r--r--models/login_source.go70
1 files changed, 68 insertions, 2 deletions
diff --git a/models/login_source.go b/models/login_source.go
index b8441adcc4..0a8a92336e 100644
--- a/models/login_source.go
+++ b/models/login_source.go
@@ -39,6 +39,7 @@ const (
LoginPAM // 4
LoginDLDAP // 5
LoginOAuth2 // 6
+ LoginSSPI // 7
)
// LoginNames contains the name of LoginType values.
@@ -48,6 +49,7 @@ var LoginNames = map[LoginType]string{
LoginSMTP: "SMTP",
LoginPAM: "PAM",
LoginOAuth2: "OAuth2",
+ LoginSSPI: "SPNEGO with SSPI",
}
// SecurityProtocolNames contains the name of SecurityProtocol values.
@@ -63,6 +65,7 @@ var (
_ core.Conversion = &SMTPConfig{}
_ core.Conversion = &PAMConfig{}
_ core.Conversion = &OAuth2Config{}
+ _ core.Conversion = &SSPIConfig{}
)
// LDAPConfig holds configuration for LDAP login source.
@@ -140,6 +143,25 @@ func (cfg *OAuth2Config) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}
+// SSPIConfig holds configuration for SSPI single sign-on.
+type SSPIConfig struct {
+ AutoCreateUsers bool
+ AutoActivateUsers bool
+ StripDomainNames bool
+ SeparatorReplacement string
+ DefaultLanguage string
+}
+
+// FromDB fills up an SSPIConfig from serialized format.
+func (cfg *SSPIConfig) FromDB(bs []byte) error {
+ return json.Unmarshal(bs, cfg)
+}
+
+// ToDB exports an SSPIConfig to a serialized format.
+func (cfg *SSPIConfig) ToDB() ([]byte, error) {
+ return json.Marshal(cfg)
+}
+
// LoginSource represents an external way for authorizing users.
type LoginSource struct {
ID int64 `xorm:"pk autoincr"`
@@ -176,6 +198,8 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
source.Cfg = new(PAMConfig)
case LoginOAuth2:
source.Cfg = new(OAuth2Config)
+ case LoginSSPI:
+ source.Cfg = new(SSPIConfig)
default:
panic("unrecognized login source type: " + com.ToStr(*val))
}
@@ -212,6 +236,11 @@ func (source *LoginSource) IsOAuth2() bool {
return source.Type == LoginOAuth2
}
+// IsSSPI returns true of this source is of the SSPI type.
+func (source *LoginSource) IsSSPI() bool {
+ return source.Type == LoginSSPI
+}
+
// HasTLS returns true of this source supports TLS.
func (source *LoginSource) HasTLS() bool {
return ((source.IsLDAP() || source.IsDLDAP()) &&
@@ -264,6 +293,11 @@ func (source *LoginSource) OAuth2() *OAuth2Config {
return source.Cfg.(*OAuth2Config)
}
+// SSPI returns SSPIConfig for this source, if of SSPI type.
+func (source *LoginSource) SSPI() *SSPIConfig {
+ return source.Cfg.(*SSPIConfig)
+}
+
// CreateLoginSource inserts a LoginSource in the DB if not already
// existing with the given name.
func CreateLoginSource(source *LoginSource) error {
@@ -300,6 +334,38 @@ func LoginSources() ([]*LoginSource, error) {
return auths, x.Find(&auths)
}
+// LoginSourcesByType returns all sources of the specified type
+func LoginSourcesByType(loginType LoginType) ([]*LoginSource, error) {
+ sources := make([]*LoginSource, 0, 1)
+ if err := x.Where("type = ?", loginType).Find(&sources); err != nil {
+ return nil, err
+ }
+ return sources, nil
+}
+
+// ActiveLoginSources returns all active sources of the specified type
+func ActiveLoginSources(loginType LoginType) ([]*LoginSource, error) {
+ sources := make([]*LoginSource, 0, 1)
+ if err := x.Where("is_actived = ? and type = ?", true, loginType).Find(&sources); err != nil {
+ return nil, err
+ }
+ return sources, nil
+}
+
+// IsSSPIEnabled returns true if there is at least one activated login
+// source of type LoginSSPI
+func IsSSPIEnabled() bool {
+ if !HasEngine {
+ return false
+ }
+ sources, err := ActiveLoginSources(LoginSSPI)
+ if err != nil {
+ log.Error("ActiveLoginSources: %v", err)
+ return false
+ }
+ return len(sources) > 0
+}
+
// GetLoginSourceByID returns login source by given ID.
func GetLoginSourceByID(id int64) (*LoginSource, error) {
source := new(LoginSource)
@@ -719,8 +785,8 @@ func UserSignIn(username, password string) (*User, error) {
}
for _, source := range sources {
- if source.IsOAuth2() {
- // don't try to authenticate against OAuth2 sources
+ if source.IsOAuth2() || source.IsSSPI() {
+ // don't try to authenticate against OAuth2 and SSPI sources here
continue
}
authUser, err := ExternalUserLogin(nil, username, password, source, true)