Exemple #1
0
        public async Task <IActionResult> StoreData([FromBody] StoreSessionDataRequest request)
        {
            if (request == null)
            {
                return(new NotFoundResult());
            }
            if (string.IsNullOrEmpty(request.Key))
            {
                return(new NotFoundResult());
            }
            if (!string.IsNullOrEmpty(request.Data) && request.Data.Length > 4096)
            {
                return(new NotFoundResult());
            }
            var spa = _externalSpaStore.GetRecord(request.Key);

            if (spa == null)
            {
                return(new NotFoundResult());
            }
            var key = $".extSpa.Session.{request.Key}";

            SessionCacheManager <string>
            .Insert(_httpContextAccessor.HttpContext, key, request.Data);

            return(new OkResult());
        }
        public async Task <IActionResult> OnGetCallbackAsync(string returnUrl = null, string prompt = null, string remoteError = null)
        {
            string currentNameIdClaimValue = null;

            if (User.Identity.IsAuthenticated)
            {
                // we will only create a new user if the user here is actually new.
                var qName = from claim in User.Claims
                            where claim.Type == ".nameIdentifier"
                            select claim;
                var nc = qName.FirstOrDefault();
                currentNameIdClaimValue = nc?.Value;
            }
            var oidc = await HarvestOidcDataAsync();

            var session = _httpContextAccessor.HttpContext.Session;

            if (remoteError != null)
            {
                ErrorMessage = $"Error from external provider: {remoteError}";
                return(RedirectToPage("./Login"));
            }
            var info = await _signInManager.GetExternalLoginInfoAsync();

            if (info == null)
            {
                return(RedirectToPage("./Login"));
            }

            // Sign in the user with this external login provider if the user already has a login.

            /*
             * var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor : true);
             * if (result.Succeeded)
             * {
             *     _logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider);
             *     return LocalRedirect(Url.GetLocalUrl(returnUrl));
             * }
             */
            var query = from claim in info.Principal.Claims
                        where claim.Type == "DisplayName"
                        select claim;
            var queryNameId = from claim in info.Principal.Claims
                              where claim.Type == ClaimTypes.NameIdentifier
                              select claim;
            var nameClaim   = query.FirstOrDefault();
            var displayName = nameClaim.Value;
            var nameIdClaim = queryNameId.FirstOrDefault();

            if (!string.IsNullOrEmpty(currentNameIdClaimValue) &&
                (currentNameIdClaimValue != nameIdClaim.Value))
            {
                session.Clear();
            }
            if (currentNameIdClaimValue == nameIdClaim.Value)
            {
                session.SetObject(".identity.oidc", oidc);
                session.SetObject(".identity.strongLoginUtc", DateTimeOffset.UtcNow);
                // this is a re login from the same user, so don't do anything;
                return(LocalRedirect(Url.GetLocalUrl(returnUrl)));
            }
            // paranoid
            var leftoverUser = await _userManager.FindByEmailAsync(displayName);

            if (leftoverUser != null)
            {
                await _userManager.DeleteAsync(leftoverUser); // just using this inMemory userstore as a scratch holding pad
            }
            var user = new ApplicationUser {
                UserName = nameIdClaim.Value, Email = displayName
            };

            // SHA256 is disposable by inheritance.
            using (var sha256 = SHA256.Create())
            {
                // Send a sample text to hash.
                var hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(nameIdClaim.Value));
                // Get the hashed string.
                var hash = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
                SessionCacheManager <string> .Insert(_httpContextAccessor.HttpContext, ".identity.userHash", hash);
            }
            var result = await _userManager.CreateAsync(user);

            var newUser = await _userManager.FindByIdAsync(user.Id);

            var cQuery = from claim in _settings.Value.PostLoginClaims
                         let c = new Claim(claim.Name, claim.Value)
                                 select c;
            var eClaims = cQuery.ToList();

            eClaims.Add(new Claim("custom-name", displayName));
            eClaims.Add(new Claim(".nameIdentifier", nameIdClaim.Value));// normalized id.
            await _userManager.AddClaimsAsync(newUser, eClaims);

            if (result.Succeeded)
            {
                await _signInManager.SignInAsync(user, isPersistent : false);

                await _userManager.DeleteAsync(user); // just using this inMemory userstore as a scratch holding pad

                _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
                session.SetObject(".identity.oidc", oidc);
                session.SetObject(".identity.strongLoginUtc", DateTimeOffset.UtcNow);
                //      _httpContextAccessor.HttpContext.DropBlueGreenApplicationCookie(_deploymentOptions);

                return(LocalRedirect(Url.GetLocalUrl(returnUrl)));
            }

            return(RedirectToPage("./Login"));
        }
        public async Task <IActionResult> Index(string id)
        {
            Logger.LogInformation("Hello from the External SPA Home Index Controller");
            var spa = _externalSpaStore.GetRecord(id);

            if (spa == null)
            {
                return(new NotFoundResult());
            }

            var loadedSpas = SessionCacheManager <Dictionary <string, ExternalSPARecord> > .Grab(_httpContextAccessor.HttpContext,
                                                                                                 _loadedSpasKey) ?? new Dictionary <string, ExternalSPARecord>();


            var result = HttpContext.User.Claims.Select(
                c => new ClaimType {
                Type = c.Type, Value = c.Value
            });

            var cacheKey = $".extSpaViewBagRecord.{id}";

            ViewBagRecord viewBagRecord = null;
            var           value         = await _cache.GetAsync(cacheKey);

            if (value != null)
            {
                viewBagRecord = ZeroFormatterSerializer.Deserialize <ViewBagRecord>(value);
            }
            else
            {
                var doc = await _discoveryCache.GetAsync();

                var request = new AuthorizeRequest(doc.AuthorizeEndpoint);
                var url     = request.CreateAuthorizeUrl(
                    clientId: spa.ClientId,
                    responseType: OidcConstants.ResponseTypes.Code,
                    prompt: OidcConstants.PromptModes.None,
                    redirectUri: spa.RedirectUri,
                    scope: "openid profile email");
                var mySpaRecord = new MySpaRecord()
                {
                    ClientId      = spa.ClientId,
                    Key           = spa.Key,
                    RedirectUri   = spa.RedirectUri,
                    CacheBustHash = spa.CacheBustHash
                };
                viewBagRecord = new ViewBagRecord {
                    AuthorizeEndpoint = doc.AuthorizeEndpoint,
                    AuthorizeUrl      = url, SpaRecord = mySpaRecord
                };
                var val = ZeroFormatterSerializer.Serialize(viewBagRecord);
                var cacheEntryOptions = new DistributedCacheEntryOptions()
                                        .SetSlidingExpiration(TimeSpan.FromMinutes(5));
                _cache.Set(cacheKey, val, cacheEntryOptions);
            }

            ViewBag.ViewBagRecord = viewBagRecord;
            if (!loadedSpas.ContainsKey(id))
            {
                loadedSpas.Add(id, spa);
                SessionCacheManager <Dictionary <string, ExternalSPARecord> >
                .Insert(_httpContextAccessor.HttpContext, _loadedSpasKey, loadedSpas);
            }
            var key        = $".extSpa.Session.{viewBagRecord.SpaRecord.Key}";
            var customData = SessionCacheManager <string>
                             .Grab(_httpContextAccessor.HttpContext, key);

            ViewBag.CacheBustHash = viewBagRecord.SpaRecord.CacheBustHash;
            ViewBag.CustomData    = customData;
            return(View(spa.View, result));
        }