Skip to content
Snippets Groups Projects
Commit 3980db2d authored by Peter Hegman's avatar Peter Hegman :basketball: Committed by Heinrich Lee Yu
Browse files

Auto refresh SAML connection after 7 day timeout

Auto redirect to provider
parent c1be1689
No related branches found
No related tags found
No related merge requests found
Showing
with 140 additions and 38 deletions
%hr.footer-fixed
.container.footer-container
.footer-links
- unless public_visibility_restricted?
= link_to _("Explore"), explore_root_path
= link_to _("Help"), help_path
= link_to _("About GitLab"), "https://about.gitlab.com/"
= footer_message
Loading
Loading
@@ -38,12 +38,4 @@
.col-sm-5.order-1.order-sm-12.new-session-forms-container
= yield
 
%hr.footer-fixed
.container.footer-container
.footer-links
- if !public_visibility_restricted?
= link_to _("Explore"), explore_root_path
= link_to _("Help"), help_path
= link_to _("About GitLab"), "https://about.gitlab.com/"
= footer_message
= render 'devise/shared/footer', footer_message: footer_message
!!! 5
%html{ lang: "en", class: system_message_class }
%html.devise-layout-html{ lang: "en", class: system_message_class }
= render "layouts/head"
%body.ui-indigo.login-page.application.navless{ class: "#{client_class_list}" }
= header_message
Loading
Loading
@@ -11,11 +11,4 @@
= render "layouts/flash"
= yield
 
%hr
.container
.footer-links
- if !public_visibility_restricted?
= link_to _("Explore"), explore_root_path
= link_to _("Help"), help_path
= link_to _("About GitLab"), "https://about.gitlab.com/"
= footer_message
= render 'devise/shared/footer', footer_message: footer_message
Loading
Loading
@@ -80,10 +80,13 @@ Please note that the certificate [fingerprint algorithm](#additional-providers-a
 
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5291) in GitLab 11.8.
- [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/9255) in GitLab 11.11 with ongoing enforcement in the GitLab UI.
- [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/292811) in GitLab 13.8, with an updated timeout experience.
 
With this option enabled, users must go through your group's GitLab single sign-on URL. They may also be added via SCIM, if configured. Users can't be added manually, and may only access project/group resources via the UI by signing in through the SSO URL.
 
However, users are not prompted to sign in through SSO on each visit. GitLab checks whether a user has authenticated through SSO, and only prompts the user to sign in via SSO if the session has expired.
However, users are not prompted to sign in through SSO on each visit. GitLab checks whether a user
has authenticated through SSO. If it's been more than 7 days since the last sign-in, GitLab
prompts the user to sign in again through SSO.
You can see more information about how long a session is valid in our [user profile documentation](../../profile/#why-do-i-keep-getting-signed-out).
 
We intend to add a similar SSO requirement for [Git and API activity](https://gitlab.com/gitlab-org/gitlab/-/issues/9152).
Loading
Loading
import { redirectUserWithSSOIdentity } from 'ee/saml_sso';
import UsernameValidator from '~/pages/sessions/new/username_validator';
import initConfirmDangerModal from '~/confirm_danger_modal';
 
new UsernameValidator(); // eslint-disable-line no-new
initConfirmDangerModal();
redirectUserWithSSOIdentity();
export const AUTO_REDIRECT_TO_PROVIDER_BUTTON_SELECTOR = '#js-auto-redirect-to-provider';
import { AUTO_REDIRECT_TO_PROVIDER_BUTTON_SELECTOR } from './constants';
export const redirectUserWithSSOIdentity = () => {
const signInButton = document.querySelector(AUTO_REDIRECT_TO_PROVIDER_BUTTON_SELECTOR);
if (!signInButton) {
return;
}
signInButton.click();
};
Loading
Loading
@@ -23,6 +23,9 @@ def saml
@group_name = unauthenticated_group.full_name
@group_saml_identity = linked_identity
@idp_url = unauthenticated_group.saml_provider.sso_url
@auto_redirect_to_provider = current_user&.group_sso?(unauthenticated_group)
render layout: 'devise_empty' if @auto_redirect_to_provider
end
 
def unlink
Loading
Loading
Loading
Loading
@@ -14,11 +14,11 @@ def saml_link_for_provider(text, provider, **args)
saml_link(text, provider.group.full_path, **args)
end
 
def saml_link(text, group_path, redirect: nil, html_class: 'btn')
def saml_link(text, group_path, redirect: nil, html_class: 'btn', id: nil)
redirect ||= group_path(group_path)
url = omniauth_authorize_path(:user, :group_saml, group_path: group_path, redirect_to: redirect)
 
link_to(text, url, method: :post, class: html_class)
link_to(text, url, method: :post, class: html_class, id: id)
end
end
end
- page_title _('SAML SSO for %{group_name}') % { group_name: @group_name }
 
= render 'devise/shared/tab_single', tab_title: _('SAML SSO')
.login-box
.login-body
- if @group_saml_identity || !user_signed_in?
%h4= _('Sign in to "%{group_name}"') % { group_name: @group_name }
- else
%h4= _('Allow "%{group_name}" to sign you in') % { group_name: @group_name }
- if @auto_redirect_to_provider
.gl-spinner-container
.gl-spinner.gl-spinner-dark.gl-spinner-lg{ aria: { label: 'Loading' } }
.gl-text-center.gl-mt-7
%h4= _('Reauthenticating with SAML provider.')
= saml_link _('Sign in with Single Sign-On'), @group_path, id: 'js-auto-redirect-to-provider', html_class: 'gl-display-none', redirect: @redirect_path
- else
= render 'devise/shared/tab_single', tab_title: _('SAML SSO')
.login-box
.login-body
- if @group_saml_identity || !user_signed_in?
%h4= _('Sign in to "%{group_name}"') % { group_name: @group_name }
- else
%h4= _('Allow "%{group_name}" to sign you in') % { group_name: @group_name }
 
%p= _('The "%{group_path}" group allows you to sign in with your Single Sign-On Account') % { group_path: @group_path }
%p= _('The "%{group_path}" group allows you to sign in with your Single Sign-On Account') % { group_path: @group_path }
 
- if @group_saml_identity || !user_signed_in?
%p= _("This will redirect you to an external sign in page.")
- if @group_saml_identity || !user_signed_in?
%p= _("This will redirect you to an external sign in page.")
 
= saml_link _('Sign in with Single Sign-On'), @group_path, html_class: 'btn btn-success btn-block qa-saml-sso-signin-button', redirect: @redirect_path
- else
.card.card-body.bs-callout-warning
= _("Only proceed if you trust %{idp_url} to control your GitLab account sign in.") % { idp_url: @idp_url }
= saml_link _('Sign in with Single Sign-On'), @group_path, html_class: 'btn btn-success btn-md gl-button btn-block qa-saml-sso-signin-button', redirect: @redirect_path
- else
.card.card-body.bs-callout-warning
= _("Only proceed if you trust %{idp_url} to control your GitLab account sign in.") % { idp_url: @idp_url }
 
= saml_link _('Authorize'), @group_path, html_class: 'btn btn-success btn-block qa-saml-sso-signin-button'
= saml_link _('Authorize'), @group_path, html_class: 'btn btn-success btn-md gl-button btn-block qa-saml-sso-signin-button'
---
title: Automatically redirect users to SAML provider after 7 day expiration
merge_request: 50914
author:
type: changed
Loading
Loading
@@ -100,6 +100,30 @@
expect(response).to redirect_to(sso_group_saml_providers_path(group))
end
end
context 'when current user has a SAML provider configured' do
let(:saml_provider) { create(:saml_provider, group: group, enforced_sso: true) }
let(:identity) { create(:group_saml_identity, saml_provider: saml_provider) }
before do
sign_out(user)
sign_in(identity.user)
end
it 'renders `devise_empty` template' do
get :saml, params: { group_id: group }
expect(response).to render_template('devise_empty')
end
end
context 'when current user does not have a SAML provider configured' do
it 'renders `devise` template' do
get :saml, params: { group_id: group }
expect(response).to render_template('devise')
end
end
end
 
context 'saml_provider is unconfigured for the group' do
Loading
Loading
Loading
Loading
@@ -100,4 +100,24 @@
end
end
end
context 'when SAML session expires' do
before do
mock_group_saml(uid: identity.extern_uid)
end
it 'shows loading screen and link used for auto-redirect' do
visit group_path(group)
click_link 'Sign in with Single Sign-On'
days_after_timeout = Gitlab::Auth::GroupSaml::SsoEnforcer::DEFAULT_SESSION_TIMEOUT + 2.days
travel_to(days_after_timeout.from_now) do
visit group_path(group)
expect(page).to have_content('Reauthenticating with SAML provider.')
expect(page).to have_selector('#js-auto-redirect-to-provider', visible: false)
end
end
end
end
import { redirectUserWithSSOIdentity } from 'ee/saml_sso';
describe('redirectUserWithSSOIdentity', () => {
describe('when auto redirect link exists', () => {
let link;
beforeEach(() => {
link = document.createElement('a');
link.setAttribute('id', 'js-auto-redirect-to-provider');
link.setAttribute('href', 'https://foobar.com/sso-service');
link.click = jest.fn();
document.body.appendChild(link);
});
afterEach(() => {
document.body.innerHTML = '';
});
it('clicks the link', () => {
redirectUserWithSSOIdentity();
expect(link.click).toHaveBeenCalled();
});
});
describe('when auto redirect link does not exist', () => {
it('does nothing', () => {
expect(redirectUserWithSSOIdentity()).toBeUndefined();
});
});
});
Loading
Loading
@@ -23124,6 +23124,9 @@ msgstr ""
msgid "Real-time features"
msgstr ""
 
msgid "Reauthenticating with SAML provider."
msgstr ""
msgid "Rebase"
msgstr ""
 
Loading
Loading
Loading
Loading
@@ -61,8 +61,6 @@ module QA
 
page.visit managed_group_url
 
EE::Page::Group::SamlSSOSignIn.perform(&:click_sign_in)
expect(page).to have_content("Already signed in with SAML for #{@group.path}")
end
end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment