diff --git a/config/routes.rb b/config/routes.rb
index 3b3d35a3..df9245de 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -2,9 +2,8 @@ require 'sidekiq/web'
 Rails.application.routes.draw do
   start = Time.now
 
-  # Sidekiq
-  constraints ->(req) { req.env["warden"].authenticate?(scope: :user) &&
-                        req.env["warden"].user.has_role?(:administrator) } do
+  # Routes only accessible by admins (admin panels, sidekiq, pghero)
+  authenticate :user, ->(user) { user.has_role?(:administrator) } do
     # Admin panel
     mount RailsAdmin::Engine => "/justask_admin", as: "rails_admin"
 
@@ -19,9 +18,8 @@ Rails.application.routes.draw do
     match "/admin/announcements/:id", to: "announcement#destroy", via: :delete, as: :announcement_destroy
   end
 
-  # Moderation panel
-  constraints ->(req) { req.env["warden"].authenticate?(scope: :user) &&
-                        req.env["warden"].user.mod? } do
+  # Routes only accessible by moderators (moderation panel)
+  authenticate :user, ->(user) { user.mod? } do
     match '/moderation/unmask', to: 'moderation#toggle_unmask', via: :post, as: :moderation_toggle_unmask
     match '/moderation/priority(/:user_id)', to: 'moderation#priority', via: :get, as: :moderation_priority
     match '/moderation/ip/:user_id', to: 'moderation#ip', via: :get, as: :moderation_ip
diff --git a/spec/integration/role_constrained_routes_spec.rb b/spec/integration/role_constrained_routes_spec.rb
index 27969ca1..cd613f20 100644
--- a/spec/integration/role_constrained_routes_spec.rb
+++ b/spec/integration/role_constrained_routes_spec.rb
@@ -6,8 +6,9 @@ require "support/pghero_stubby"
 describe "role-constrained routes", type: :request do
   shared_examples_for "fails to access route" do
     it "fails to access route" do
+      # 302 = redirect to login
       # 404 = no user found -- we have a fallback route if something could not be matched
-      expect(subject).to eq 404
+      expect(subject).to be_in [302, 404]
     end
   end