diff --git a/resources/static/dialog/controllers/required_email.js b/resources/static/dialog/controllers/required_email.js
index cd83eda405a2eb22c33587438f5665d85328215a..77b05df67fd932b51e553fc261e2731f7f345723 100644
--- a/resources/static/dialog/controllers/required_email.js
+++ b/resources/static/dialog/controllers/required_email.js
@@ -129,29 +129,30 @@ BrowserID.Modules.RequiredEmail = (function() {
         // (without a password). Otherwise, make the user verify the address
         // (which shows no password).
         var userOwnsEmail = !!user.getStoredEmailKeypair(email);
-        showTemplate({
-          signin: userOwnsEmail,
-          showPassword: false
-        });
+        showTemplate({ signin: userOwnsEmail, showPassword: false });
         ready();
       }
       else {
         user.addressInfo(email, function(info) {
           if(info.type === "primary") {
-            // For a primary, they should authenticate with the IdP, the normal
-            // process will take care of the rest.
-            self.close("primary_user", _.extend(info, { email: email }));
-            ready();
+            user.isUserAuthenticatedToPrimary(email, info, function(authed) {
+              if(authed) {
+                showTemplate({ signin: true, showPassword: false });
+              }
+              else {
+                // For unauthed primary, they should authenticate with the IdP,
+                // the normal process will take care of the rest.
+                self.close("primary_user", _.extend({ email: email }, info));
+              }
+              ready();
+            }, self.getErrorDialog(errors.addressInfo, ready));
           }
           else {
             var registered = info.known;
             // If the current email address is registered but the user is not
             // authenticated, make them sign in with it.  Otherwise, make them
             // verify ownership of the address.
-            showTemplate({
-              signin: registered,
-              showPassword: registered
-            });
+            showTemplate({ signin: registered, showPassword: registered });
             ready();
           }
         }, self.getErrorDialog(errors.addressInfo, ready));
diff --git a/resources/static/shared/user.js b/resources/static/shared/user.js
index 0380ba78a4299cac74924f39d958c56a1b24ea35..1771c153636c7bb8b0cee5c4f435bd7e143c3073 100644
--- a/resources/static/shared/user.js
+++ b/resources/static/shared/user.js
@@ -369,33 +369,99 @@ BrowserID.User = (function() {
       }
     },
 
+    /**
+     * A full provision a primary user, if they are authenticated, save their
+     * cert/keypair, and authenticate them to BrowserID.
+     * @method provisionPrimaryUser
+     * @param {string} email
+     * @param {object} info - provisioning info
+     * @param {function} [onComplete] - called when complete.  Called with
+     * status field and info. Status can be:
+     *  primary.already_added
+     *  primary.verified
+     *  primary.verify
+     *  primary.could_not_add
+     * @param {function} [onFailure] - called on failure
+     */
     provisionPrimaryUser: function(email, info, onComplete, onFailure) {
-      provisioning({
-        email: email,
-        url: info.prov
-      }, function(keypair, cert) {
-        persistEmailKeypair(email, "primary", keypair, cert, function() {
-          // We are getting an assertion for browserid.org.
-          User.getAssertion(email, "https://browserid.org", function(assertion) {
-            if (assertion) {
-              onComplete("primary.verified", {
-                assertion: assertion
-              });
-            }
-            else {
-              // XXX change this to could_not_provision
-              onComplete("primary.could_not_add");
+      User.primaryUserAuthenticationInfo(email, info, function(authInfo) {
+        if(authInfo.authenticated) {
+          persistEmailKeypair(email, "primary", authInfo.keypair, authInfo.cert,
+            function() {
+              // We are getting an assertion for browserid.org.
+              User.getAssertion(email, "https://browserid.org", function(assertion) {
+                if (assertion) {
+                  onComplete("primary.verified", {
+                    assertion: assertion
+                  });
+                }
+                else {
+                  // XXX change this to could_not_provision
+                  onComplete("primary.could_not_add");
+                }
+              }, onFailure);
             }
-          }, onFailure);
-        }, onFailure);
-      }, function(error) {
-        if (error.code === "primaryError" && error.msg === "user is not authenticated as target user") {
-          onComplete("primary.verify", info);
+          );
         }
         else {
-          onFailure(info);
+          onComplete("primary.verify", info);
         }
-      });
+      }, onFailure);
+    },
+
+    /**
+     * Get the IdP authentication info for a user.
+     * @method primaryUserAuthenticationInfo
+     * @param {string} email
+     * @param {object} info - provisioning info
+     * @param {function} [onComplete] - called when complete.  Called with
+     * provisioning info as well as keypair, cert, and authenticated.
+     *   authenticated - boolean, true if user is authenticated with primary.
+     *    false otw.
+     *   keypair - returned if user is authenticated.
+     *   cert - returned if user is authenticated.
+     * @param {function} [onFailure] - called on failure
+     */
+    primaryUserAuthenticationInfo: function(email, info, onComplete, onFailure) {
+      provisioning(
+        { email: email, url: info.prov },
+        function(keypair, cert) {
+          var userInfo = _.extend({
+            keypair: keypair,
+            cert: cert,
+            authenticated: true
+          }, info);
+
+          onComplete(userInfo);
+        },
+        function(error) {
+          if (error.code === "primaryError" && error.msg === "user is not authenticated as target user") {
+            var userInfo = _.extend({
+              authenticated: false
+            }, info);
+            onComplete(userInfo);
+          }
+          else {
+            onFailure(info);
+          }
+        }
+      );
+
+    },
+
+    /**
+     * Get the IdP authentication status for a user.
+     * @method isUserAuthenticatedToPrimary
+     * @param {string} email
+     * @param {object} info - provisioning info
+     * @param {function} [onComplete] - called when complete.  Called with
+     *   status field - true if user authenticated with IdP, false otw.
+     * @param {function} [onFailure] - called on failure
+     */
+    isUserAuthenticatedToPrimary: function(email, info, onComplete, onFailure) {
+      User.primaryUserAuthenticationInfo(email, info, function(authInfo) {
+        onComplete(authInfo.authenticated);
+      }, onFailure);
     },
 
     /**
diff --git a/resources/static/test/qunit/controllers/required_email_unit_test.js b/resources/static/test/qunit/controllers/required_email_unit_test.js
index 9ad563aa7bf326941630bc8160edff731ed25d5b..d9b582ce7e2b3052b0c9a12e1a94a8dc40f8d582 100644
--- a/resources/static/test/qunit/controllers/required_email_unit_test.js
+++ b/resources/static/test/qunit/controllers/required_email_unit_test.js
@@ -43,7 +43,8 @@
       user = bid.User,
       testHelpers = bid.TestHelpers,
       register = testHelpers.register,
-      mediator = bid.Mediator;
+      provisioning = bid.Mocks.Provisioning;
+
 
   module("controllers/required_email", {
     setup: function() {
@@ -123,22 +124,38 @@
     });
   });
 
-  asyncTest("user who is not authenticated, primary - user must validate with IdP.", function() {
+  asyncTest("user who is not authenticated, authenticated with IdP - user sees sign in screen.", function() {
+    var email = "unregistered@testuser.com";
+
+    xhr.useResult("primary");
+    provisioning.setStatus(provisioning.AUTHENTICATED);
+
+    createController({
+      email: email,
+      authenticated: false,
+      ready: function() {
+        testSignIn(email, testNoPasswordSection);
+      }
+    });
+  });
+
+  asyncTest("user who is not authenticated, not authenticated with IdP - user sees verification screen.", function() {
     var email = "unregistered@testuser.com",
         msgInfo;
 
-    mediator.subscribe("primary_user", function(msg, info) {
+    register("primary_user", function(msg, info) {
       msgInfo = info;
     });
 
     xhr.useResult("primary");
+    provisioning.setStatus(provisioning.NOT_AUTHENTICATED);
+
     createController({
       email: email,
       authenticated: false,
       ready: function() {
-        equal(msgInfo.email, "unregistered@testuser.com", "correct email address");
+        equal(msgInfo && msgInfo.email, "unregistered@testuser.com", "correct email address");
         start();
-
       }
     });
   });
diff --git a/resources/static/test/qunit/shared/user_unit_test.js b/resources/static/test/qunit/shared/user_unit_test.js
index c0591f97a4aa4118baa8068745b2a294e5af6220..b191f8590c080a47120d221593b1980500211220 100644
--- a/resources/static/test/qunit/shared/user_unit_test.js
+++ b/resources/static/test/qunit/shared/user_unit_test.js
@@ -243,6 +243,110 @@ var vep = require("./vep");
     start();
   });
 
+  asyncTest("provisionPrimaryUser authenticated with IdP, expect primary.verified", function() {
+    xhr.useResult("primary");
+    provisioning.setStatus(provisioning.AUTHENTICATED);
+
+    lib.provisionPrimaryUser("unregistered@testuser.com", {},
+      function(status, info) {
+        equal(status, "primary.verified", "primary user is already verified, correct status");
+        start();
+      },
+      testHelpers.unexpectedXHRFailure
+    );
+  });
+
+  asyncTest("provisionPrimaryUser not authenticated with IdP, expect primary.verify", function() {
+    xhr.useResult("primary");
+    provisioning.setStatus(provisioning.NOT_AUTHENTICATED);
+
+    lib.provisionPrimaryUser("unregistered@testuser.com", {},
+      function(status, info) {
+        equal(status, "primary.verify", "primary user is not verified, correct status");
+        start();
+      },
+      testHelpers.unexpectedXHRFailure
+    );
+  });
+
+  asyncTest("provisionPrimaryUser with provisioning failure - call failure", function() {
+    xhr.useResult("primary");
+    provisioning.setFailure("failure");
+
+    lib.provisionPrimaryUser("unregistered@testuser.com", {},
+      testHelpers.unexpectedSuccess,
+      testHelpers.expectedXHRFailure
+    );
+  });
+
+  asyncTest("primaryUserAuthenticationInfo, user authenticated to IdP, expect keypair, cert, authenticated status", function() {
+    provisioning.setStatus(provisioning.AUTHENTICATED);
+
+    lib.primaryUserAuthenticationInfo("testuser@testuser.com", {},
+      function(info) {
+        equal(info.authenticated, true, "user is authenticated");
+        ok(info.keypair, "keypair passed");
+        ok(info.cert, "cert passed");
+        start();
+      },
+      testHelpers.unexpectedXHRError
+    );
+  });
+
+  asyncTest("primaryUserAuthenticationInfo, user not authenticated to IdP, expect false authenticated status", function() {
+    provisioning.setStatus(provisioning.NOT_AUTHENTICATED);
+
+    lib.primaryUserAuthenticationInfo("testuser@testuser.com", {},
+      function(info) {
+        equal(info.authenticated, false, "user is not authenticated");
+        start();
+      },
+      testHelpers.unexpectedXHRError
+    );
+  });
+
+  asyncTest("primaryUserAuthenticationInfo with XHR failure", function() {
+    provisioning.setFailure("failure");
+
+    lib.primaryUserAuthenticationInfo("testuser@testuser.com", {},
+      testHelpers.unexpectedSuccess,
+      testHelpers.expectedXHRFailure
+    );
+  });
+
+  asyncTest("isUserAuthenticatedToPrimary with authed user, expect true status", function() {
+    provisioning.setStatus(provisioning.AUTHENTICATED);
+
+    lib.isUserAuthenticatedToPrimary("testuser@testuser.com", {},
+      function(status) {
+        equal(status, true, "user is authenticated, correct status");
+        start();
+      },
+      testHelpers.unexpectedXHRError
+    );
+  });
+
+  asyncTest("isUserAuthenticatedToPrimary with non-authed user, expect false status", function() {
+    provisioning.setStatus(provisioning.NOT_AUTHENTICATED);
+
+    lib.isUserAuthenticatedToPrimary("testuser@testuser.com", {},
+      function(status) {
+        equal(status, false, "user is not authenticated, correct status");
+        start();
+      },
+      testHelpers.unexpectedXHRError
+    );
+  });
+
+  asyncTest("isUserAuthenticatedToPrimary with failure", function() {
+    provisioning.setFailure("failure");
+
+    lib.isUserAuthenticatedToPrimary("testuser@testuser.com", {},
+      testHelpers.unexpectedSuccess,
+      testHelpers.expectedXHRFailure
+    );
+  });
+
   asyncTest("waitForUserValidation with `complete` response", function() {
     storage.setStagedOnBehalfOf(testOrigin);
 
@@ -534,7 +638,6 @@ var vep = require("./vep");
     });
   });
 
-
   asyncTest("isEmailRegistered with registered email", function() {
     lib.isEmailRegistered("registered@testuser.com", function(registered) {
       ok(registered);