Add setting to OAuth handlers to skip local 2FA authentication (#16594)

This PR adds a setting to OAuth and OpenID login sources to allow the source to
skip local 2FA authentication.

Fix #13939

Signed-off-by: Andrew Thornton <art27@cantab.net>
tokarchuk/v1.17
zeripath 3 years ago committed by GitHub
parent 51578d6418
commit 9ca0e7905c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      cmd/admin.go
  2. 2
      options/locale/locale_en-US.ini
  3. 1
      routers/web/admin/auths.go
  4. 20
      routers/web/user/auth.go
  5. 1
      services/auth/source/oauth2/source.go
  6. 1
      services/forms/auth_form.go
  7. 7
      templates/admin/auth/edit.tmpl
  8. 7
      templates/admin/auth/source/oauth.tmpl

@ -288,6 +288,10 @@ var (
Value: "", Value: "",
Usage: "Custom icon URL for OAuth2 login source", Usage: "Custom icon URL for OAuth2 login source",
}, },
cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
},
} }
microcmdAuthUpdateOauth = cli.Command{ microcmdAuthUpdateOauth = cli.Command{
@ -616,6 +620,7 @@ func parseOAuth2Config(c *cli.Context) *oauth2.Source {
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"), OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
CustomURLMapping: customURLMapping, CustomURLMapping: customURLMapping,
IconURL: c.String("icon-url"), IconURL: c.String("icon-url"),
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
} }
} }

@ -2456,6 +2456,8 @@ auths.oauth2_tokenURL = Token URL
auths.oauth2_authURL = Authorize URL auths.oauth2_authURL = Authorize URL
auths.oauth2_profileURL = Profile URL auths.oauth2_profileURL = Profile URL
auths.oauth2_emailURL = Email URL auths.oauth2_emailURL = Email URL
auths.skip_local_two_fa = Skip local 2FA
auths.skip_local_two_fa_helper = Leaving unset means local users with 2FA set will still have to pass 2FA to log on
auths.oauth2_tenant = Tenant auths.oauth2_tenant = Tenant
auths.enable_auto_register = Enable Auto Registration auths.enable_auto_register = Enable Auto Registration
auths.sspi_auto_create_users = Automatically create users auths.sspi_auto_create_users = Automatically create users

@ -181,6 +181,7 @@ func parseOAuth2Config(form forms.AuthenticationForm) *oauth2.Source {
OpenIDConnectAutoDiscoveryURL: form.OpenIDConnectAutoDiscoveryURL, OpenIDConnectAutoDiscoveryURL: form.OpenIDConnectAutoDiscoveryURL,
CustomURLMapping: customURLMapping, CustomURLMapping: customURLMapping,
IconURL: form.Oauth2IconURL, IconURL: form.Oauth2IconURL,
SkipLocalTwoFA: form.SkipLocalTwoFA,
} }
} }

@ -574,7 +574,7 @@ func SignInOAuth(ctx *context.Context) {
user, gothUser, err := oAuth2UserLoginCallback(loginSource, ctx.Req, ctx.Resp) user, gothUser, err := oAuth2UserLoginCallback(loginSource, ctx.Req, ctx.Resp)
if err == nil && user != nil { if err == nil && user != nil {
// we got the user without going through the whole OAuth2 authentication flow again // we got the user without going through the whole OAuth2 authentication flow again
handleOAuth2SignIn(ctx, user, gothUser) handleOAuth2SignIn(ctx, loginSource, user, gothUser)
return return
} }
@ -660,7 +660,7 @@ func SignInOAuthCallback(ctx *context.Context) {
} }
} }
handleOAuth2SignIn(ctx, u, gothUser) handleOAuth2SignIn(ctx, loginSource, u, gothUser)
} }
func getUserName(gothUser *goth.User) string { func getUserName(gothUser *goth.User) string {
@ -702,18 +702,22 @@ func updateAvatarIfNeed(url string, u *models.User) {
} }
} }
func handleOAuth2SignIn(ctx *context.Context, u *models.User, gothUser goth.User) { func handleOAuth2SignIn(ctx *context.Context, source *models.LoginSource, u *models.User, gothUser goth.User) {
updateAvatarIfNeed(gothUser.AvatarURL, u) updateAvatarIfNeed(gothUser.AvatarURL, u)
// If this user is enrolled in 2FA, we can't sign the user in just yet. needs2FA := false
// Instead, redirect them to the 2FA authentication page. if !source.Cfg.(*oauth2.Source).SkipLocalTwoFA {
_, err := models.GetTwoFactorByUID(u.ID) _, err := models.GetTwoFactorByUID(u.ID)
if err != nil { if err != nil && !models.IsErrTwoFactorNotEnrolled(err) {
if !models.IsErrTwoFactorNotEnrolled(err) {
ctx.ServerError("UserSignIn", err) ctx.ServerError("UserSignIn", err)
return return
} }
needs2FA = err == nil
}
// If this user is enrolled in 2FA and this source doesn't override it,
// we can't sign the user in just yet. Instead, redirect them to the 2FA authentication page.
if !needs2FA {
if err := ctx.Session.Set("uid", u.ID); err != nil { if err := ctx.Session.Set("uid", u.ID); err != nil {
log.Error("Error setting uid in session: %v", err) log.Error("Error setting uid in session: %v", err)
} }

@ -24,6 +24,7 @@ type Source struct {
OpenIDConnectAutoDiscoveryURL string OpenIDConnectAutoDiscoveryURL string
CustomURLMapping *CustomURLMapping CustomURLMapping *CustomURLMapping
IconURL string IconURL string
SkipLocalTwoFA bool
// reference to the loginSource // reference to the loginSource
loginSource *models.LoginSource loginSource *models.LoginSource

@ -66,6 +66,7 @@ type AuthenticationForm struct {
Oauth2EmailURL string Oauth2EmailURL string
Oauth2IconURL string Oauth2IconURL string
Oauth2Tenant string Oauth2Tenant string
SkipLocalTwoFA bool
SSPIAutoCreateUsers bool SSPIAutoCreateUsers bool
SSPIAutoActivateUsers bool SSPIAutoActivateUsers bool
SSPIStripDomainNames bool SSPIStripDomainNames bool

@ -255,6 +255,13 @@
<label for="open_id_connect_auto_discovery_url">{{.i18n.Tr "admin.auths.openIdConnectAutoDiscoveryURL"}}</label> <label for="open_id_connect_auto_discovery_url">{{.i18n.Tr "admin.auths.openIdConnectAutoDiscoveryURL"}}</label>
<input id="open_id_connect_auto_discovery_url" name="open_id_connect_auto_discovery_url" value="{{$cfg.OpenIDConnectAutoDiscoveryURL}}"> <input id="open_id_connect_auto_discovery_url" name="open_id_connect_auto_discovery_url" value="{{$cfg.OpenIDConnectAutoDiscoveryURL}}">
</div> </div>
<div class="optional field">
<div class="ui checkbox">
<label for="skip_local_two_fa"><strong>{{.i18n.Tr "admin.auths.skip_local_two_fa"}}</strong></label>
<input id="skip_local_two_fa" name="skip_local_two_fa" type="checkbox" {{if $cfg.SkipLocalTwoFA}}checked{{end}}>
<p class="help">{{.i18n.Tr "admin.auths.skip_local_two_fa_helper"}}</p>
</div>
</div>
<div class="oauth2_use_custom_url inline field"> <div class="oauth2_use_custom_url inline field">
<div class="ui checkbox"> <div class="ui checkbox">

@ -28,6 +28,13 @@
<label for="open_id_connect_auto_discovery_url">{{.i18n.Tr "admin.auths.openIdConnectAutoDiscoveryURL"}}</label> <label for="open_id_connect_auto_discovery_url">{{.i18n.Tr "admin.auths.openIdConnectAutoDiscoveryURL"}}</label>
<input id="open_id_connect_auto_discovery_url" name="open_id_connect_auto_discovery_url" value="{{.open_id_connect_auto_discovery_url}}"> <input id="open_id_connect_auto_discovery_url" name="open_id_connect_auto_discovery_url" value="{{.open_id_connect_auto_discovery_url}}">
</div> </div>
<div class="optional field">
<div class="ui checkbox">
<label for="skip_local_two_fa"><strong>{{.i18n.Tr "admin.auths.skip_local_two_fa"}}</strong></label>
<input id="skip_local_two_fa" name="skip_local_two_fa" type="checkbox" {{if .skip_local_two_fa}}checked{{end}}>
<p class="help">{{.i18n.Tr "admin.auths.skip_local_two_fa_helper"}}</p>
</div>
</div>
<div class="oauth2_use_custom_url inline field"> <div class="oauth2_use_custom_url inline field">
<div class="ui checkbox"> <div class="ui checkbox">

Loading…
Cancel
Save