5

I am building a MVC 5 web application that uses cookie authentication as primary authentication method.

Our application flow goes like this:

  1. First time user signs up with username/password to create an IdentityUser.
  2. User signs in with his username/password
  3. User associates one or more Google and/or Microsoft accounts with his "local" account.
  4. OWIN Google and Microsoft providers handle external authentication.
  5. We use simple delegate method to read returned access_token and refresh_token and store it as identity claims.
  6. We use access token to make API calls server side.
  7. We use refresh token to get new access token when one is expired.

The question is, what is the best place to implemnt access token validation, expiration and renewal. I would really appreciate if somebody could lead me to a right direction.

var googleCreds = new GoogleOAuth2AuthenticationOptions
{
    ClientId = "833250754551-qg564a5g29f0l37q0egqimcoklpjf6dj.apps.googleusercontent.com",
    ClientSecret = "YpY_u07KQU4kjhPWH5vuiMzz"
    Provider = new Microsoft.Owin.Security.Google.GoogleOAuth2AuthenticationProvider
    {
        OnApplyRedirect = context =>
        {
            var queryString = HttpContext.Current.Request.QueryString.ToString();
            var queryParms = HttpUtility.ParseQueryString(queryString);

            string redirect = context.RedirectUri;
            redirect += "&access_type=offline";
            redirect += "&approval_prompt=force";
            redirect += "&include_granted_scopes=true";

            var uri = new Uri(redirect);

            if ((!string.IsNullOrEmpty(queryParms.Get("scope"))))
            {
                var scope = queryParms.Get("scope");
                var redirectQueryString = HttpUtility.ParseQueryString(uri.Query);
                switch (scope)
                {
                    case "GooglePlus":
                        redirectQueryString.Set("scope", "https://www.googleapis.com/auth/plus.login");
                        break;
                    case "YoutTube":
                        redirectQueryString.Set("scope", "https://gdata.youtube.com");
                        break;
                    default:
                        throw new Exception("Invalid scope passed in: scope: " + scope);
                }

                redirect = uri.GetLeftPart(UriPartial.Path) + "?" + redirectQueryString.ToString();
            }

            context.Response.Redirect(redirect);

        },
        OnAuthenticated = context =>
        {
            TimeSpan expiryDuration = context.ExpiresIn ?? new TimeSpan();
            context.Identity.AddClaim(new Claim("urn:tokens:google:email", context.Email));
            context.Identity.AddClaim(new Claim("urn:tokens:google:url", context.GivenName)); 
            if (!String.IsNullOrEmpty(context.RefreshToken))
            {
                context.Identity.AddClaim(new Claim("urn:tokens:google:refreshtoken", context.RefreshToken));
            }
            context.Identity.AddClaim(new Claim("urn:tokens:google:accesstoken", context.AccessToken));
            context.Identity.AddClaim(new Claim("urn:tokens:google:accesstokenexpiry", DateTime.Now.Add(expiryDuration).ToString()));

            return Task.FromResult<object>(null);
        }
    }
}; 

app.UseGoogleAuthentication(googleCreds);
ppalms
  • 394
  • 2
  • 7
  • 19
jjarv
  • 71
  • 6

0 Answers0