Interfaces

Project

FormIdentification

NuGet packageOwin.Framework.FormIdentification
GitHub sourceOwinFramework.FormIdentification

Home |  Readme

The OwinFramework.FormIdentification Project

This middleware allows users of your website to:

  • Create an account using an email address and a password.
  • Ask for a remember me cookie to be stored on their browser so that they don't have to log in again each time they visit the website.
  • Log into an existing account using the email address and password used to create the account.
  • Verify their email address by clicking a one-time activiation link in the welcome email.
  • Change their password by providing their current password and a new one.
  • Change their email address by providing their current email and password.
  • Confirm their new email address by clicking a link in the confirmation email.
  • Revert the email address change by clicking a link in an email that is sent to the original email address.
  • Logout, securing their account and deleting the remember me cookie.
  • Request a time-limited password reset email to be sent.
  • Click the single use link in the password reset email and reset their password without knowing their current password.
Note that there are other middleware packages that provide user identification from social media, shared secrets and certificates. These middleware packages will all work togther because each one will look to see if the user is already identified before trying to perform its own identification. The first middleware in the pipeline that successfully identifies the user will supply the user identity to the rest of the pipeline and other identification middleware will not make any additional user identification attempts after the user is identified.
Note that their are other types of middleware designed to be an additional identification factor. These multi-factor identification middleware will perform the secondary identification after another middleware has succesfully identified the caller. These multi-factor identification middlewares should run after the primary identification because they generally need an identified user to work. For example a secondary identification based on IP address will look at the user identified by the earlier middleware, look up the last known IP address for this user, and verrify that the current resquest is from the same IP address.

Cookies

Note that this middleware can store a cookie on the browser to indicate who the user is logged in as. The lifetime of the cookie is configurable and defaults to 90 days. To keep this cookie secure this middleware performs a few extra redirections that mean that the cookie can be stored on the browser in a different domain than the non secure pages of the site are served from.

When a browser makes a request to a server it includes all of the cookies that are stored for that domain (for example www.mycompany.com). If the login request set cookies in the www.mycompany.com domain then every time the browser requested any page in the www.mycompany.com domain it would send the cookie, and if any of these requests are not encrypted (even requets for images or stylesheets etc) then anyone watching could copy the cookie value and use it to impersonate that user for 90 days.

For this reason this middleware assumes that you will use a sub-domain for log in etc and store cookies in this sub-domain on the browser so that they will not be sent with non secure page requests. You don't have to do this and it will still work, but you must then make sure all requests to your site are secure (using HTTPS) and if a user types HTTP into their browser their user account will be at risk even if your server does not handle the request.

Lets assume that your main site domain is http://www.mycompany.com/ and you choose to use https://secure.mycompany.com/ for login, this is what happens when a user visits your site:

  1. The very first time they visit http://www.mycompany.com/ this middleware will notice that there is no login token in session and will redirect the browser to a page on the secure sub-domain, for example https://secure.mycompany.com/renewSession. Since this is their first visit and no cookies have been set, tihs will store a value in session indicating that they are an anonymous user and redirect them back to the page that they initially requested. Now when the browser re-requests http://www.mycompany.com/ this middleware will find the anonymous token in session and serve the page as an unidentified user.
  2. For subsequent requests during the session, requests will continue to be processed as an unidentified user. When the session times out, the process will revert back to step 1.
  3. If the user decides to sign in by POSTing to https://secure.mycompany.com/signin then this middleware will check their credentials and respond with a page containing a cookie that identifies the user and Javascript to load https://secure.mycompany.com/renewSession. This will store the user identification cookie on the browser in the secure.mycompany.com domain and load https://secure.mycompany.com/renewSession.
  4. When the browser makes a request to https://secure.mycompany.com/renewSession is will include the cookies for the secure.mycompany.com domain, including the user identification cookie. This middleware will handle this request by putting information into the users session about their identity, and redirecting back to the page they first came from on http://www.mycompany.com/.
  5. When this middleware receives a request for http://www.mycompany.com/ it will see the user's identity in their session and process the request as that identified user. Note that the browser does not send the user identification cookie because this is for a different domain (www.mycompany.com instead of secure.mycompany.com).
  6. If the user's session expires whilst they are logged on, then this middleware will redirect the browser to https://secure.mycompany.com/renewSession. When the browser makes this request, because it is for the secure.mycompany.com domain the user identification cookie will be included in the request. This middleware will handle this request by storing the user identity in the new session just like in step 4.

Adding this middleware to the Owin pipeline

builder.Register(ninject.Get<OwinFramework.FormIdentification.FormIdentificationMiddleware>())
    .As("Form identification")
    .ConfigureWith(config, "/owinFramework/middleware/formIdentification");
The assumes that you are using Ninject as your IoC container, and followed the getting started walkthrough. If this is not the case then you will need to adjust the code to work in your application.

Default Configuration

The configuration below is the configuration you will get by default if you do not provide a configuration for this middleware.

{
   "owinFramework": {
      "middleware": {
         "formIdentification": {
            "secureProtocol": "https",
            "secureDomain": "",
            "documentationPage": "/formId/config",
            "signupPage": "/formId/signup",
            "signupSuccessPage": "/welcome",
            "signupFailPage": "/formId/signup",
            "signinPage": "/formId/signin",
            "signinSuccessPage": "/",
            "signinFailPage": "/formId/signin",
            "signoutPage": "/formId/signout",
            "signoutSuccessPage": "/",
            "changePasswordPage": "/formId/changePassword",
            "changePasswordSuccessPage": "/",
            "changePasswordFailPage": "/formId/changePassword",
            "changeEmailPage": "/formId/changeEmail",
            "changeEmailSuccessPage": "/",
            "changeEmailFailPage": "/formId/changeEmail",
            "sendPasswordResetPage": "/formId/sendPasswordReset",
            "sendPasswordResetSuccessPage": "/",
            "sendPasswordResetFailPage": "/formId/sendPasswordReset",
            "resetPasswordPage": "/formId/resetPassword",
            "resetPasswordSuccessPage": "/",
            "resetPasswordFailPage": "/formId/resetPassword",
            "verifyEmailPage": "/formId/verifyEmail",
            "verifyEmailSuccessPage": "/emailVerified",
            "verifyEmailFailPage": "/emailNotVerified",
            "revertEmailPage": "/formId/revertEmail",
            "revertEmailSuccessPage": ""/emailReverted",
            "revertEmailFailPage": "/emailNotReverted",
            "renewSessionPage": "/formId/renew",
            "updateIdentityPage": "/formId/update",
            "cookieName": "form-identification",
            "sessionIdentityName": "form-identification-identity",
            "sessionPurposeName": "form-identification-purpose",
            "sessionStatusName": "form-identification-status",
            "sessionRememberMeName": "form-identification-rememberme",
            "sessionClaimsName": "form-identification-claims",
            "sessionIsAnonymousName": "form-dentification-anonymous",
            "rememberMeFor": "90d",
            "emailFormField": "email",
            "passwordFormField": "password",
            "newPasswordFormField": "newPassword",
            "rememberMeFormField": "rememberMe",
            "tokenFormField": "token",
            "newEmailFormField": "newEmail",
            "identityFormField": "id",
            "passwordResetTokenType": "PasswordReset",
            "passwordResetEmailFrom": "",
            "passwordResetEmailSubject": "Reset your password",
            "emailChangeEmailFrom": "",
            "emailChangeEmailSubject": "Email address updated",
            "verifyEmailTokenType": "VerifyEmail",
            "revertEmailTokenType": "RevertEmail",
            "welcomeEmailFrom": "",
            "welcomeEmailSubject": "Thank you for creating an account"
         }
      }
   }
}

Configuration Documentation