예제 #1
0
        public async Task <IHttpActionResult> HandleResponseFromApple()
        {
            try
            {
                // TODO should probably check state here (and in the non-Apple one)

                InitialTokenResponse response = new InitialTokenResponse();
                response.code  = HttpContext.Current.Request.Form["code"];
                response.user  = HttpContext.Current.Request.Form["user"];
                response.state = HttpContext.Current.Request.Form["state"]; //use state as client's requested return uri

                // Create a new instance of AppleAuthProvider
                AppleAuthProvider provider = new AppleAuthProvider(
                    ConfigurationManager.AppSettings["oauth:apple:id"],
                    ConfigurationManager.AppSettings["oauth:apple:teamid"],
                    ConfigurationManager.AppSettings["oauth:apple:keyid"],
                    //"https://webhook.site/cb4691d4-fdaf-4250-8613-a9ed1623453b",//
                    string.Format("https://{0}/api/account/HandleResponseFromApple", Request.RequestUri.Authority),
                    response.state);
                // Retrieve an authorization token
                AuthorizationToken authorizationToken = await provider.GetAuthorizationToken(response.code, ConfigurationManager.AppSettings["oauth:apple:secret"]);

                var             login = new UserLoginInfo("Apple", authorizationToken.UserInformation.UserID);
                ApplicationUser user  = await UserManager.FindAsync(login);

                if (user == null && string.IsNullOrWhiteSpace(response.user))
                {
                    // new user but apple didn't give details
                    return(InternalServerError(new Exception("Something went wrong while getting your details from Apple. Please remove OurPlace from your 'Sign in with Apple' security settings and try again.")));
                }

                // apple only returns the user's details on the first authentication
                if (user == null && !string.IsNullOrWhiteSpace(response.user))
                {
                    dynamic appleUser = JsonConvert.DeserializeObject(response.user);

                    user = new ApplicationUser
                    {
                        UserName     = appleUser.email,
                        Email        = appleUser.email,
                        FirstName    = appleUser.name.firstName,
                        Surname      = appleUser.name.lastName,
                        DateCreated  = DateTime.UtcNow,
                        AuthProvider = "Apple",
                        Trusted      = false,
                        LastConsent  = DateTime.UtcNow
                    };

                    ApplicationUser existingResult = await UserManager.FindByEmailAsync(user.Email);

                    if (existingResult == null)
                    {
                        // New user
                        IdentityResult createResult = await UserManager.CreateAsync(user);

                        if (!createResult.Succeeded)
                        {
                            return(GetErrorResult(createResult));
                        }
                    }
                    else
                    {
                        // user already exists with that email
                        user.Id = existingResult.Id;
                        await UserManager.UpdateAsync(user);
                    }

                    // Add this oauth login to the user account
                    IdentityResult idResult = await UserManager.AddLoginAsync(user.Id, login);

                    if (!idResult.Succeeded)
                    {
                        return(GetErrorResult(idResult));
                    }
                }
                else
                {
                    // existing user
                    Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
                }

                ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, OAuthDefaults.AuthenticationType);

                ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager, CookieAuthenticationDefaults.AuthenticationType);

                AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
                properties = await AddRefreshToken(oAuthIdentity, properties);

                Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);

                user.LastConsent = DateTime.UtcNow;
                await UserManager.UpdateAsync(user);

                Dictionary <string, string> args = new Dictionary <string, string>()
                {
                    { "grant_type", "refresh_token" },
                    { "refresh_token", properties.Dictionary["refresh_token"] }
                };
                RefreshResponse refResp;

                using (var client = new HttpClient())
                {
                    HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, string.Format("https://{0}/Token", Request.RequestUri.Authority))
                    {
                        Content = new FormUrlEncodedContent(args)
                    };
                    HttpResponseMessage resp = await client.SendAsync(req);

                    if (resp.Content == null || !resp.IsSuccessStatusCode)
                    {
                        throw new Exception("Couldn't get an access token");
                    }
                    string json = await resp.Content.ReadAsStringAsync();

                    refResp = JsonConvert.DeserializeObject <RefreshResponse>(json);
                }

                return(Redirect(string.Format("{0}#access_token={1}&token_type=bearer&expires_in={2}&refresh_token={3}&refresh_token_expires={4}",
                                              response.state,
                                              refResp.Access_token,
                                              refResp.Expires_in,
                                              properties.Dictionary["refresh_token"],
                                              properties.Dictionary["refresh_token_expires"])));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return(InternalServerError(new Exception(string.Format("HandleResponseFromApple\nkey{2}\n{0}\n{1}", e.Message, e.StackTrace, ConfigurationManager.AppSettings["oauth:apple:secret"]))));
            }
        }
예제 #2
0
        public async Task <ActionResult> HandleResponseFromApple(InitialTokenResponse response)
        {
            try
            {
                // TODO should probably check state here but MVC seems to have different session IDs for each request yay

                // Create a new instance of AppleAuthProvider
                AppleAuthProvider provider = new AppleAuthProvider(
                    ConfigurationManager.AppSettings["oauth:apple:id"],
                    ConfigurationManager.AppSettings["oauth:apple:teamid"],
                    ConfigurationManager.AppSettings["oauth:apple:keyid"],
                    string.Format("https://{0}/account/HandleResponseFromApple", Request.Url.Authority),
                    Session.SessionID);
                // Retrieve an authorization token
                AuthorizationToken authorizationToken = await provider.GetAuthorizationToken(response.code, ConfigurationManager.AppSettings["oauth:apple:secret"]);

                var             login = new UserLoginInfo("Apple", authorizationToken.UserInformation.UserID);
                ApplicationUser user  = await UserManager.FindAsync(login);

                // apple only returns the user's details on the first authentication
                if (user == null && !string.IsNullOrWhiteSpace(response.user))
                {
                    dynamic appleUser = JsonConvert.DeserializeObject(response.user);

                    ApplicationUser appUser = new ApplicationUser
                    {
                        UserName     = appleUser.email,
                        Email        = appleUser.email,
                        FirstName    = appleUser.name.firstName,
                        Surname      = appleUser.name.lastName,
                        DateCreated  = DateTime.UtcNow,
                        AuthProvider = "Apple",
                        Trusted      = false,
                        LastConsent  = DateTime.UtcNow
                    };

                    ApplicationUser existingResult = await UserManager.FindByEmailAsync(appUser.Email);

                    if (existingResult == null)
                    {
                        // New user
                        IdentityResult createResult = await UserManager.CreateAsync(appUser);

                        if (!createResult.Succeeded)
                        {
                            return(RedirectToAction("Login"));
                        }
                    }
                    else
                    {
                        // user already exists with that email
                        appUser = existingResult;
                    }

                    // Add this oauth login to the user account
                    IdentityResult idResult = await UserManager.AddLoginAsync(appUser.Id, login);

                    if (!idResult.Succeeded)
                    {
                        return(RedirectToAction("Login"));
                    }

                    ClaimsIdentity oAuthIdentity = await appUser.GenerateUserIdentityAsync(UserManager,
                                                                                           OAuthDefaults.AuthenticationType);

                    ClaimsIdentity cookieIdentity = await appUser.GenerateUserIdentityAsync(UserManager,
                                                                                            CookieAuthenticationDefaults.AuthenticationType);

                    AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(appUser.UserName);
                    await SignInManager.SignInAsync(appUser, true, true);

                    Request.GetOwinContext().Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);

                    return(RedirectToLocal("/"));
                }
                else if (user != null)
                {
                    // existing user
                    ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, OAuthDefaults.AuthenticationType);

                    ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager, CookieAuthenticationDefaults.AuthenticationType);

                    AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
                    Request.GetOwinContext().Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);

                    user.LastConsent = DateTime.UtcNow;
                    await UserManager.UpdateAsync(user);

                    return(RedirectToLocal("/"));
                }
                else
                {
                    // new user but apple didn't give details
                    // TODO show instructions for removing ourplace from your apple account so that it can be re-added
                    ViewData["errormessage"] = "Something went wrong while getting your details from Apple. Please remove OurPlace from your 'Sign in with Apple' security settings and try again.";
                    return(View("Error"));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                ViewData["errormessage"] = string.Format("HandleResponseFromApple\nkey{2}\n{0}\n{1}", e.Message, e.StackTrace, ConfigurationManager.AppSettings["oauth:apple:secret"]);
                return(View("Error"));
            }
        }