diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index 91e6975e2694eafd7a5a01a3a115199fd3184d1d..02ea91602e8ee3f360fd8fd2ea04968b417a716f 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -118,6 +118,10 @@ header {
       }
     }
   }
+
+  .impersonation i {
+    color: $red-normal;
+  }
 }
 
 @mixin collapsed-header {
diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb
index 56e24386463db3a95e794faf0ed9ed83df635336..9083bfb41cfdb494dcba62e0bb6ec25186dbdfbd 100644
--- a/app/controllers/admin/application_controller.rb
+++ b/app/controllers/admin/application_controller.rb
@@ -8,4 +8,10 @@ class Admin::ApplicationController < ApplicationController
   def authenticate_admin!
     return render_404 unless current_user.is_admin?
   end
+
+  def authorize_impersonator!
+    if session[:impersonator_id]
+      User.find_by!(username: session[:impersonator_id]).admin?
+    end
+  end
 end
diff --git a/app/controllers/admin/impersonation_controller.rb b/app/controllers/admin/impersonation_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0382402afa6432de55f9c14e4b0a13dd825f5e88
--- /dev/null
+++ b/app/controllers/admin/impersonation_controller.rb
@@ -0,0 +1,32 @@
+class Admin::ImpersonationController < Admin::ApplicationController
+  skip_before_action :authenticate_admin!, only: :destroy
+
+  before_action :user
+  before_action :authorize_impersonator!
+
+  def create
+    session[:impersonator_id] = current_user.username
+    session[:impersonator_return_to] = request.env['HTTP_REFERER']
+
+    warden.set_user(user, scope: 'user')
+
+    flash[:alert] = "You are impersonating #{user.username}."
+
+    redirect_to root_path
+  end
+
+  def destroy
+    redirect = session[:impersonator_return_to]
+
+    warden.set_user(user, scope: 'user')
+
+    session[:impersonator_return_to] = nil
+    session[:impersonator_id] = nil
+
+    redirect_to redirect || root_path
+  end
+
+  def user
+    @user ||= User.find_by!(username: params[:id] || session[:impersonator_id])
+  end
+end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index c63d0793e3141dde9c10d2fb500b374004d04d08..d7c927d444cbc4b43d0d5bfe20f63bb8e2c5a5c8 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -63,12 +63,6 @@ class Admin::UsersController < Admin::ApplicationController
     end
   end
 
-  def login_as
-    sign_in(user)
-    flash[:alert] = "Logged in as #{user.username}"
-    redirect_to root_path
-  end
-
   def disable_two_factor
     user.disable_two_factor!
     redirect_to admin_user_path(user),
diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml
index 4245d0f1eda1f52b3c84c7f830493af0acc87775..8d1cab4137c4950c5c557482a7e3e899b658cac7 100644
--- a/app/views/admin/users/_head.html.haml
+++ b/app/views/admin/users/_head.html.haml
@@ -7,7 +7,7 @@
 
   .pull-right
     - unless @user == current_user
-      = link_to 'Log in as this user', login_as_admin_user_path(@user), method: :post, class: "btn btn-grouped btn-info"
+      = link_to 'Impersonate', impersonate_admin_user_path(@user), method: :post, class: "btn btn-grouped btn-info"
     = link_to edit_admin_user_path(@user), class: "btn btn-grouped" do
       %i.fa.fa-pencil-square-o
       Edit
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index c31b1cbe9a8ab8aaa030154f203a182d4365b46c..13eeb0fe20b78b98ebb49ba83e29cf6151857c83 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -13,6 +13,10 @@
           %li.visible-sm.visible-xs
             = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do
               = icon('search')
+          - if session[:impersonator_id]
+            %li.impersonation
+              = link_to stop_impersonation_admin_users_path, method: :delete, title: 'Stop impersonation', data: { toggle: 'tooltip', placement: 'bottom' } do
+                = icon('user-secret fw')
           - if current_user.is_admin?
             %li
               = link_to admin_root_path, title: 'Admin area', data: {toggle: 'tooltip', placement: 'bottom'} do
diff --git a/config/routes.rb b/config/routes.rb
index f6812c9280a8819ed7e022904626ab1d7a4c75cc..6ebedaefafea27547d9968173aec9b9981938831 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -212,6 +212,8 @@ Gitlab::Application.routes.draw do
       resources :keys, only: [:show, :destroy]
       resources :identities, only: [:index, :edit, :update, :destroy]
 
+      delete 'stop_impersonation' => 'impersonation#destroy', on: :collection
+
       member do
         get :projects
         get :keys
@@ -221,7 +223,7 @@ Gitlab::Application.routes.draw do
         put :unblock
         put :unlock
         put :confirm
-        post :login_as
+        post 'impersonate' => 'impersonation#create'
         patch :disable_two_factor
         delete 'remove/:email_id', action: 'remove_email', as: 'remove_email'
       end
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index fcbe62cace85c9f243e489679fb82b486d8fc488..8b7af4d3a0aa94542ab494ca663693142ac4b409 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -7,21 +7,6 @@ describe Admin::UsersController do
     sign_in(admin)
   end
 
-  describe 'POST login_as' do
-    let(:user) { create(:user) }
-
-    it 'logs admin as another user' do
-      expect(warden.authenticate(scope: :user)).not_to eq(user)
-      post :login_as, id: user.username
-      expect(warden.authenticate(scope: :user)).to eq(user)
-    end
-
-    it 'redirects user to homepage' do
-      post :login_as, id: user.username
-      expect(response).to redirect_to(root_path)
-    end
-  end
-
   describe 'DELETE #user with projects' do
     let(:user) { create(:user) }
     let(:project) { create(:project, namespace: user.namespace) }
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index c2c7364f6c51b59dd9d75182f2d3b85a3577ccb4..4c756a8e73230191cfdd89f14ebb710383d5aef0 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -111,24 +111,50 @@ describe "Admin::Users", feature: true  do
       expect(page).to have_content(@user.name)
     end
 
-    describe 'Login as another user' do
-      it 'should show login button for other users and check that it works' do
-        another_user = create(:user)
+    describe 'Impersonation' do
+      let(:another_user) { create(:user) }
+      before { visit admin_user_path(another_user) }
 
-        visit admin_user_path(another_user)
-
-        click_link 'Log in as this user'
+      context 'before impersonating' do
+        it 'shows impersonate button for other users' do
+          expect(page).to have_content('Impersonate')
+        end
 
-        expect(page).to have_content("Logged in as #{another_user.username}")
+        it 'should not show impersonate button for admin itself' do
+          visit admin_user_path(@user)
 
-        page.within '.sidebar-user .username' do
-          expect(page).to have_content(another_user.username)
+          expect(page).not_to have_content('Impersonate')
         end
       end
 
-      it 'should not show login button for admin itself' do
-        visit admin_user_path(@user)
-        expect(page).not_to have_content('Log in as this user')
+      context 'when impersonating' do
+        before { click_link 'Impersonate' }
+
+        it 'logs in as the user when impersonate is clicked' do
+          page.within '.sidebar-user .username' do
+            expect(page).to have_content(another_user.username)
+          end
+        end
+
+        it 'sees impersonation log out icon' do
+          icon = first('.fa.fa-user-secret')
+
+          expect(icon).to_not eql nil
+        end
+
+        it 'can log out of impersonated user back to original user' do
+          find(:css, 'li.impersonation a').click
+
+          page.within '.sidebar-user .username' do
+            expect(page).to have_content(@user.username)
+          end
+        end
+
+        it 'is redirected back to the impersonated users page in the admin after stopping' do
+          find(:css, 'li.impersonation a').click
+
+          expect(current_path).to eql "/admin/users/#{another_user.username}"
+        end
       end
     end