diff --git a/app/assets/javascripts/discourse/views/modal/login_view.js b/app/assets/javascripts/discourse/views/modal/login_view.js
index f11712ab3..57b88dca1 100644
--- a/app/assets/javascripts/discourse/views/modal/login_view.js
+++ b/app/assets/javascripts/discourse/views/modal/login_view.js
@@ -109,6 +109,10 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
     return window.open("/auth/github", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top);
   },
 
+  personaLogin: function() {
+      navigator.id.request();
+  },
+
   authenticationComplete: function(options) {
     if (options.awaiting_approval) {
       this.flash(Em.String.i18n('login.awaiting_approval'), 'success');
diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb
index f876fcdde..50350b36a 100644
--- a/app/controllers/users/omniauth_callbacks_controller.rb
+++ b/app/controllers/users/omniauth_callbacks_controller.rb
@@ -21,6 +21,8 @@ class Users::OmniauthCallbacksController < ApplicationController
       create_or_sign_on_user_using_openid(auth_token)
     when "github"
       create_or_sign_on_user_using_github(auth_token)
+    when "persona"
+      create_or_sign_on_user_using_persona(auth_token)
     end
   end
 
@@ -169,6 +171,7 @@ class Users::OmniauthCallbacksController < ApplicationController
         openid_url: identity_url
       }
     end
+
   end
 
   def create_or_sign_on_user_using_github(auth_token)
@@ -200,6 +203,37 @@ class Users::OmniauthCallbacksController < ApplicationController
     else
       @data[:name] = screen_name
     end
+
+  end
+
+  def create_or_sign_on_user_using_persona(auth_token)
+
+    email = auth_token[:info][:email]
+
+    user = User.find_by_email(email)
+
+    if user
+      if SiteSetting.must_approve_users? and !user.approved?
+        @data = {awaiting_approval: true}
+      else
+        log_on_user(user)
+        @data = {authenticated: true}
+      end
+    else
+      @data = {
+        email: email,
+        email_valid: true,
+        name: User.suggest_name(email),
+        username: User.suggest_username(email),
+        auth_provider: params[:provider].try(:capitalize)
+      }
+
+      session[:authentication] = {
+        email: email,
+        email_valid: true,
+      }
+    end
+
   end
 
 end
diff --git a/app/views/common/_persona_javascript.html.erb b/app/views/common/_persona_javascript.html.erb
new file mode 100644
index 000000000..f6448e28a
--- /dev/null
+++ b/app/views/common/_persona_javascript.html.erb
@@ -0,0 +1,25 @@
+<script src="https://login.persona.org/include.js"></script>
+<form id="persona_assertion_form" action="/auth/persona/callback" method="post" target="_blank">
+  <input type='hidden' name='assertion'/>
+</form>
+<script>
+  (function() {
+    var readyCalled = false;
+    navigator.id.watch({
+      onlogin: function(assertion) {
+        if (readyCalled) {
+          $('#persona_assertion_form input[name=assertion]').val(assertion);
+          $('#persona_assertion_form').submit();
+        }
+      },
+      onlogout: function() {
+        if (readyCalled) {
+          Discourse.logout();
+        }
+      },
+      onready: function() {
+        readyCalled = true;
+      }
+    });
+  }());
+</script>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index e1b44ca5b..a3fd6e0a9 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -58,6 +58,7 @@
     <footer id='bottom'></footer>
 
     <%= render :partial => "common/discourse_javascript" %>
+    <%= render :partial => "common/persona_javascript" %>
     <%= render_google_analytics_code %>
 
     <!-- Discourse Version: <%= Discourse::VERSION::STRING %> -->