public static AuthenticationTransaction PrepareAuthentication(this HttpContext context, string callbackUrl, string returnUrl)
        {
            var middlewareOptions = context.RequestServices.GetRequiredService<IOptions<OpenIdConnectOptions>>().Value;
            var nonce = middlewareOptions.ProtocolValidator.GenerateNonce();

            // Add the nonce.
            context.Response.Cookies.Append(
                OpenIdConnectDefaults.CookieNoncePrefix + middlewareOptions.StringDataFormat.Protect(nonce),
                NonceProperty,
                new CookieOptions
                {
                    HttpOnly = true,
                    Secure = context.Request.IsHttps,
                    Expires = DateTimeOffset.UtcNow + middlewareOptions.ProtocolValidator.NonceLifetime
                });

            // Prepare state.
            var authenticationProperties = new AuthenticationProperties() { RedirectUri = returnUrl };
            AddCallbackUrl(callbackUrl, authenticationProperties);
            GenerateCorrelationId(context, middlewareOptions, authenticationProperties);

            // Generate state.
            var state = Uri.EscapeDataString(middlewareOptions.StateDataFormat.Protect(authenticationProperties));

            // Return nonce to the Lock.
            return new AuthenticationTransaction(nonce, state);
        }
Beispiel #2
0
        public async Task ExecuteResultAsync_InvokesSignInAsyncOnConfiguredScheme()
        {
            // Arrange
            var principal = new ClaimsPrincipal();
            var authProperties = new AuthenticationProperties();
            var authenticationManager = new Mock<AuthenticationManager>();
            authenticationManager
                .Setup(c => c.SignInAsync("Scheme1", principal, authProperties))
                .Returns(TaskCache.CompletedTask)
                .Verifiable();
            var httpContext = new Mock<HttpContext>();
            httpContext.Setup(c => c.RequestServices).Returns(CreateServices());
            httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object);
            var result = new SignInResult("Scheme1", principal, authProperties);
            var routeData = new RouteData();

            var actionContext = new ActionContext(
                httpContext.Object,
                routeData,
                new ActionDescriptor());

            // Act
            await result.ExecuteResultAsync(actionContext);

            // Assert
            authenticationManager.Verify();
        }
Beispiel #3
0
 /// <summary>
 /// Main constructor to create <see cref="BasicAuthInfo"/>
 /// </summary>
 /// <param name="credential">Basic auth credential from the request</param>
 /// <param name="properties">Basic auth properties from the request</param>
 /// <param name="httpContext">Context from the request</param>
 /// <param name="authenticationScheme">Authentication scheme from the configuration</param>
 internal BasicAuthInfo(BasicAuthCredential credential, AuthenticationProperties properties, HttpContext httpContext, string authenticationScheme)
 {
     this.Credential = credential;
     this.Properties = properties;
     this.HttpContext = httpContext;
     this.AuthenticationScheme = authenticationScheme;
 }
 /// <summary>
 /// Creates a new context object.
 /// </summary>
 /// <param name="context">The HTTP request context.</param>
 /// <param name="options">The Twitter middleware options.</param>
 /// <param name="properties">The authentication properties of the challenge.</param>
 /// <param name="redirectUri">The initial redirect URI.</param>
 public TwitterRedirectToAuthorizationEndpointContext(HttpContext context, TwitterOptions options,
     AuthenticationProperties properties, string redirectUri)
     : base(context, options)
 {
     RedirectUri = redirectUri;
     Properties = properties;
 }
 /// <summary>
 /// Creates a new context object.
 /// </summary>
 /// <param name="context">The HTTP request context.</param>
 /// <param name="options">The <see cref="OAuthOptions"/>.</param>
 /// <param name="properties">The authentication properties of the challenge.</param>
 /// <param name="redirectUri">The initial redirect URI.</param>
 public OAuthRedirectToAuthorizationContext(HttpContext context, OAuthOptions options, AuthenticationProperties properties, string redirectUri)
     : base(context)
 {
     RedirectUri = redirectUri;
     Properties = properties;
     Options = options;
 }
 private AuthPropertiesTokenCache(AuthenticationProperties authProperties)
     : base()
 {
     _authProperties = authProperties;
     BeforeAccess = BeforeAccessNotificationWithProperties;
     AfterAccess = AfterAccessNotificationWithProperties;
     BeforeWrite = BeforeWriteNotification;
 }
 public IActionResult Google()
 {
     var props = new AuthenticationProperties
     {
         RedirectUri  = "/home/about"
     };
     
     return new ChallengeResult("Google", props);
 }
        public ActionResult Google()
        {
            var props = new AuthenticationProperties
            {
                RedirectUri = "/account/register"
            };

            return new ChallengeResult("Google", props);
        }
        // Leave it up to authentication handler to do the right thing for the challenge
        public virtual Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties)
        {
            if (string.IsNullOrEmpty(authenticationScheme))
            {
                throw new ArgumentException(nameof(authenticationScheme));
            }

            return ChallengeAsync(authenticationScheme, properties, ChallengeBehavior.Automatic);
        }
Beispiel #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AuthenticationTicket"/> class
 /// </summary>
 /// <param name="principal">the <see cref="ClaimsPrincipal"/> that represents the authenticated user.</param>
 /// <param name="properties">additional properties that can be consumed by the user or runtime.</param>
 /// <param name="authenticationScheme">the authentication middleware that was responsible for this ticket.</param>
 public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties properties, string authenticationScheme)
 {
     if (principal == null)
     {
         throw new ArgumentNullException(nameof(principal));
     }
     AuthenticationScheme = authenticationScheme;
     Principal = principal;
     Properties = properties ?? new AuthenticationProperties();
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="context"></param>
 /// <param name="options"></param>
 /// <param name="properties"></param>
 /// <param name="cookieOptions"></param>
 public CookieSigningOutContext(
     HttpContext context, 
     CookieAuthenticationOptions options, 
     AuthenticationProperties properties, 
     CookieOptions cookieOptions)
     : base(context, options)
 {
     CookieOptions = cookieOptions;
     Properties = properties;
 }
Beispiel #12
0
        public ActionResult SocialLogin([FromForm]string scheme, string returnUrl = null)
        {
            var props = new AuthenticationProperties
            {
                RedirectUri = Url.Action("sociallogincallback", "Account", new {ReturnUrl = returnUrl})
            };

            props.Items["orgId"] = HttpContext.GetTenant<Organization>().Id.ToString();

            return new ChallengeResult(scheme, props);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticationResponseGrant"/> class.
        /// </summary>
        /// <param name="principal"></param>
        /// <param name="properties"></param>
        public AuthenticationResponseGrant(ClaimsPrincipal principal, AuthenticationProperties properties)
        {
            if (principal == null)
            {
                throw new ArgumentNullException("principal");
            }

            Principal = principal;
            Identity = principal.Identities.FirstOrDefault();
            Properties = properties;
        }
 /// <summary>
 /// Creates a new instance of the context object.
 /// </summary>
 /// <param name="context">The HTTP request context</param>
 /// <param name="options">The middleware options</param>
 /// <param name="authenticationScheme">Initializes AuthenticationScheme property</param>
 /// <param name="principal">Initializes Principal property</param>
 /// <param name="properties">Initializes Properties property</param>
 public CookieSignedInContext(
     HttpContext context,
     CookieAuthenticationOptions options,
     string authenticationScheme,
     ClaimsPrincipal principal,
     AuthenticationProperties properties)
     : base(context, options)
 {
     AuthenticationScheme = authenticationScheme;
     Principal = principal;
     Properties = properties;
 }
 /// <summary>
 /// Initializes a <see cref="GoogleAuthenticatedContext"/>
 /// </summary>
 /// <param name="context">The OWIN environment</param>
 /// <param name="identity">The <see cref="ClaimsIdentity"/> representing the user</param>
 /// <param name="properties">A property bag for common authentication properties</param>
 /// <param name="responseMessage"></param>
 /// <param name="attributeExchangeProperties"></param>
 public GoogleAuthenticatedContext(
     IOwinContext context,
     ClaimsIdentity identity,
     AuthenticationProperties properties,
     XElement responseMessage,
     IDictionary<string, string> attributeExchangeProperties)
     : base(context)
 {
     Identity = identity;
     Properties = properties;
     ResponseMessage = responseMessage;
     AttributeExchangeProperties = attributeExchangeProperties;
 }
Beispiel #16
0
        public async Task<IActionResult> Login(LoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                var properties = new AuthenticationProperties
                {
                    IsPersistent = true,
                    ExpiresUtc = new DateTime(2016, 12, 31)
                };

                if (model.Password == _config.NormalUserPassword)
                {
                    var claims = new[] { new Claim("name", "user"), new Claim(ClaimTypes.Role, "User") };
                    var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                    await
                        HttpContext.Authentication.SignInAsync(
                            CookieAuthenticationDefaults.AuthenticationScheme,
                            new ClaimsPrincipal(identity), 
                            properties);
                    return RedirectToAction("Index", "User");
                }

                if (model.Password == _config.InsiderUserPassword)
                {
                    var claims = new[] { new Claim("name", "user"), new Claim(ClaimTypes.Role, "Insider") };
                    var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                    await
                        HttpContext.Authentication.SignInAsync(
                            CookieAuthenticationDefaults.AuthenticationScheme,
                            new ClaimsPrincipal(identity),
                            properties);
                    return RedirectToAction("Index", "User");
                }

                if (model.Password == _config.AdminPassword)
                {
                    var claims = new[] { new Claim("name", "user"), new Claim(ClaimTypes.Role, "Admin") };
                    var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                    await
                        HttpContext.Authentication.SignInAsync(
                            CookieAuthenticationDefaults.AuthenticationScheme,
                            new ClaimsPrincipal(identity),
                            properties);
                    return RedirectToAction("Index", "User");
                }

                ModelState.AddModelError("Password", "Hmm, das Passwort scheint ungültig zu sein. Bitte versuche es mit dem richtigen Passwort noch einmal.");
            }

            return View(model);
        }
 /// <summary>
 /// Validates whether Properties are the same as the provided ones from action result containing such property.
 /// </summary>
 /// <param name="actionResult">Action result with Properties.</param>
 /// <param name="properties">Expected authentication properties.</param>
 /// <param name="failedValidationAction">Action to call in case of failed validation.</param>
 public static void ValidateAuthenticationProperties(
     dynamic actionResult,
     AuthenticationProperties properties,
     Action<string, string, string> failedValidationAction)
 {
     var actualProperties = (AuthenticationProperties)TryGetAuthenticationProperties(actionResult);
     if (Reflection.AreNotDeeplyEqual(properties, actualProperties))
     {
         failedValidationAction(
             "authentication properties",
             "to be the same as the provided one",
             "instead received different result");
     }
 }
Beispiel #18
0
 public async Task CookieSignInAsync(User user, bool isPersistent)
 {
     await CookieSignOutCurrentUserAsync();
     var claims = new List<Claim>
     {
         new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
         new Claim(ClaimTypes.Name, user.UserName)
     };
     var identity = new ClaimsIdentity(claims);
     var principal = new ClaimsPrincipal(identity);
     var context = _accessor.HttpContext;
     var props = new AuthenticationProperties{ IsPersistent = isPersistent };
     await context.Authentication.SignInAsync(Scheme, principal, props);
 }
        public AuthPropertiesTokenCache(AuthenticationProperties authProperties) : base()
        {
            _authProperties = authProperties;
            BeforeAccess = BeforeAccessNotification;
            AfterAccess = AfterAccessNotification;
            BeforeWrite = BeforeWriteNotification;

            string cachedTokensText;
            if (authProperties.Items.TryGetValue(TokenCacheKey, out cachedTokensText))
            {
                var cachedTokens = Convert.FromBase64String(cachedTokensText);
                Deserialize(cachedTokens);
            }
        }
        public override async Task SignInAsync([NotNull] string authenticationScheme, [NotNull] ClaimsPrincipal principal, AuthenticationProperties properties)
        {
            var handler = HttpAuthenticationFeature.Handler;

            var signInContext = new SignInContext(authenticationScheme, principal, properties?.Items);
            if (handler != null)
            {
                await handler.SignInAsync(signInContext);
            }

            if (!signInContext.Accepted)
            {
                throw new InvalidOperationException($"The following authentication scheme was not accepted: {authenticationScheme}");
            }
        }
        public override async Task ChallengeAsync([NotNull] string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior)
        {
            var handler = HttpAuthenticationFeature.Handler;

            var challengeContext = new ChallengeContext(authenticationScheme, properties?.Items, behavior);
            if (handler != null)
            {
                await handler.ChallengeAsync(challengeContext);
            }

            if (!challengeContext.Accepted)
            {
                throw new InvalidOperationException($"The following authentication scheme was not accepted: {authenticationScheme}");
            }
        }
Beispiel #22
0
        /// <summary>
        /// Initializes a new instance of <see cref="SignOutResult"/> with the
        /// specified authentication schemes and <paramref name="properties"/>.
        /// </summary>
        /// <param name="authenticationSchemes">The authentication scheme to use when signing out the user.</param>
        /// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the sign-out operation.</param>
        public SignOutResult(IList<string> authenticationSchemes, AuthenticationProperties properties)
        {
            if (authenticationSchemes == null)
            {
                throw new ArgumentNullException(nameof(authenticationSchemes));
            }

            if (authenticationSchemes.Count == 0)
            {
                throw new ArgumentException(Resources.MustSpecifyAtLeastOneAuthenticationScheme, nameof(authenticationSchemes));
            }

            AuthenticationSchemes = authenticationSchemes;
            Properties = properties;
        }
        public static AuthenticationProperties GetAuthenticationProperties()
        {
            var authenticationProperties = new AuthenticationProperties
            {
                AllowRefresh = true,
                ExpiresUtc = new DateTimeOffset(new DateTime(2016, 1, 1, 1, 1, 1)),
                IsPersistent = true,
                IssuedUtc = new DateTimeOffset(new DateTime(2015, 1, 1, 1, 1, 1)),
                RedirectUri = "test"
            };

            authenticationProperties.Items.Add("TestKeyItem", "TestValueItem");
            authenticationProperties.Items.Add("AnotherTestKeyItem", "AnotherTestValueItem");

            return authenticationProperties;
        }
Beispiel #24
0
        /// <summary>
        /// Initializes a new instance of <see cref="SignInResult"/> with the
        /// specified authentication scheme and <paramref name="properties"/>.
        /// </summary>
        /// <param name="authenticationScheme">The authentication schemes to use when signing in the user.</param>
        /// <param name="principal">The claims principal containing the user claims.</param>
        /// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the sign-in operation.</param>
        public SignInResult(string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties)
        {
            if (authenticationScheme == null)
            {
                throw new ArgumentNullException(nameof(authenticationScheme));
            }

            if (principal == null)
            {
                throw new ArgumentNullException(nameof(principal));
            }

            AuthenticationScheme = authenticationScheme;
            Principal = principal;
            Properties = properties;
        }
Beispiel #25
0
        public void CanStoreMultipleTokens()
        {
            var props = new AuthenticationProperties();
            var tokens = new List<AuthenticationToken>();
            var tok1 = new AuthenticationToken { Name = "One", Value = "1" };
            var tok2 = new AuthenticationToken { Name = "Two", Value = "2" };
            var tok3 = new AuthenticationToken { Name = "Three", Value = "3" };
            tokens.Add(tok1);
            tokens.Add(tok2);
            tokens.Add(tok3);
            props.StoreTokens(tokens);

            Assert.Equal("1", props.GetTokenValue("One"));
            Assert.Equal("2", props.GetTokenValue("Two"));
            Assert.Equal("3", props.GetTokenValue("Three"));
            Assert.Equal(3, props.GetTokens().Count());
        }
        public void CanRoundTripEmptyPrincipal()
        {
            var serializer = new TicketSerializer();
            var properties = new AuthenticationProperties();
            properties.RedirectUri = "bye";
            var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello");

            using (var stream = new MemoryStream())
            using (var writer = new BinaryWriter(stream))
            using (var reader = new BinaryReader(stream))
            {
                serializer.Write(writer, ticket);
                stream.Position = 0;
                var readTicket = serializer.Read(reader);
                Assert.Equal(0, readTicket.Principal.Identities.Count());
                Assert.Equal("bye", readTicket.Properties.RedirectUri);
                Assert.Equal("Hello", readTicket.AuthenticationScheme);
            }
        }
        public void CanRoundTripBootstrapContext()
        {
            var serializer = new TicketSerializer();
            var properties = new AuthenticationProperties();

            var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello");
            ticket.Principal.AddIdentity(new ClaimsIdentity("misc") { BootstrapContext = "bootstrap" });

            using (var stream = new MemoryStream())
            using (var writer = new BinaryWriter(stream))
            using (var reader = new BinaryReader(stream))
            {
                serializer.Write(writer, ticket);
                stream.Position = 0;
                var readTicket = serializer.Read(reader);
                Assert.Equal(1, readTicket.Principal.Identities.Count());
                Assert.Equal("misc", readTicket.Principal.Identity.AuthenticationType);
                Assert.Equal("bootstrap", readTicket.Principal.Identities.First().BootstrapContext);
            }
        }
        public override async Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior)
        {
            if (string.IsNullOrEmpty(authenticationScheme))
            {
                throw new ArgumentException(nameof(authenticationScheme));
            }

            var handler = HttpAuthenticationFeature.Handler;

            var challengeContext = new ChallengeContext(authenticationScheme, properties?.Items, behavior);
            if (handler != null)
            {
                await handler.ChallengeAsync(challengeContext);
            }

            if (!challengeContext.Accepted)
            {
                throw new InvalidOperationException($"No authentication handler is configured to handle the scheme: {authenticationScheme}");
            }
        }
        public async Task<IActionResult> Ntlm(string returnUrl = null)
        {
            if (this.User.Identity.IsAuthenticated == false)
            {
                var defaultProperties = new AuthenticationProperties() { RedirectUri = returnUrl };

                var authContext = new Http.Features.Authentication.AuthenticateContext(ActiveDirectoryOptions.DefaultAuthenticationScheme);
                await HttpContext.Authentication.AuthenticateAsync(authContext);

                if (!authContext.Accepted || authContext.Principal == null)
                {
                    return new UnauthorizedResult();
                }
            }

            if (string.IsNullOrWhiteSpace(returnUrl))
                return new OkResult();
            else
                return Redirect(returnUrl);
        }
Beispiel #30
0
        public void SubsequentStoreTokenDeletesPreviousTokens()
        {
            var props = new AuthenticationProperties();
            var tokens = new List<AuthenticationToken>();
            var tok1 = new AuthenticationToken { Name = "One", Value = "1" };
            var tok2 = new AuthenticationToken { Name = "Two", Value = "2" };
            var tok3 = new AuthenticationToken { Name = "Three", Value = "3" };
            tokens.Add(tok1);
            tokens.Add(tok2);
            tokens.Add(tok3);

            props.StoreTokens(tokens);

            props.StoreTokens(new[] { new AuthenticationToken { Name = "Zero", Value = "0" } });

            Assert.Equal("0", props.GetTokenValue("Zero"));
            Assert.Equal(null, props.GetTokenValue("One"));
            Assert.Equal(null, props.GetTokenValue("Two"));
            Assert.Equal(null, props.GetTokenValue("Three"));
            Assert.Equal(1, props.GetTokens().Count());
        }
Beispiel #31
0
        public JsonResult UserLogin(string username, string password)
        {
            var userLogin = UserLoginRepo.NewInstance.Filter.UserLogin(username, password).Get.FirstOrDefault();

            if (userLogin == null || !BC.Verify(password, userLogin.Password))
            {
                return(Json(new { result = false }));
            }
            else
            {
                //Token üretiliyor.
                TokenHandler tokenHandler = new TokenHandler(configuration);
                Token.Token  token        = tokenHandler.CreateAccessToken(userLogin);

                //Refresh token Users tablosuna işleniyor.
                userLogin.RefreshToken        = token.RefreshToken;
                userLogin.RefreshTokenEndDate = token.Expiration.AddMinutes(3);

                var updateRefresh = UserLoginRepo.NewInstance.Do.Update(userLogin);

                var claims = new List <Claim>
                {
                    new Claim(ClaimTypes.Sid, userLogin.UserId.ToString()),
                    new Claim(ClaimTypes.NameIdentifier, userLogin.RefreshToken),
                    new Claim(ClaimTypes.Name, userLogin.Name + " " + userLogin.Surname),
                    new Claim(ClaimTypes.Email, userLogin.Email)
                };

                var identity  = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                var principal = new ClaimsPrincipal(identity);
                var props     = new AuthenticationProperties();
                HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, props);

                return(Json(new { result = true }));
            }
        }
Beispiel #32
0
        public IActionResult GoogleOpenIdConnectChallenge([FromQuery] string?ReturnUrl)
        {
            ReturnUrl ??= RETURN_URL_DEFAULT;

            if (!Url.IsLocalUrl(ReturnUrl))
            {
                return(BadRequest($"\"{ReturnUrl}\" is not a local url"));
            }

            AuthenticationProperties authenticationProperties = new AuthenticationProperties {
                RedirectUri = ReturnUrl,
            };

            bool isAuthenticated = User.Identity?.IsAuthenticated ?? false;

            if (isAuthenticated)
            {
                return(LocalRedirect(authenticationProperties.RedirectUri));
            }
            else
            {
                return(Challenge(authenticationProperties, new string[] { GoogleOpenIdConnectDefaults.AuthenticationScheme }));
            }
        }
        public async Task <IActionResult> Index(LoginRequest request)
        {
            if (!ModelState.IsValid)
            {
                return(View());
            }

            var result = await _userApiClient.Authenticate(request);

            var userPrincipal  = this.ValidateToken(result.ResultDataObject);
            var authProperties = new AuthenticationProperties()
            {
                ExpiresUtc   = DateTimeOffset.UtcNow.AddMinutes(30),
                IsPersistent = false
            };

            //Set session để lưu giữ khi đăng nhập thành công, nhằm check xem user đã đăng nhập hay chưa, nếu chưa sẽ chỉ hiện trang đăng nhập
            HttpContext.Session.SetString("Token", result.ResultDataObject);

            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userPrincipal,
                                          authProperties);

            return(RedirectToAction("Index", "Home"));
        }
Beispiel #34
0
        /// <InheritDoc />
        public Task ChallengeAsync(AuthenticationProperties properties)
        {
            if (properties == null)
            {
                throw new ArgumentNullException(nameof(properties));
            }

            // Don't serialize the return url twice, move it to our location.
            var redirectUri = properties.RedirectUri;
            properties.RedirectUri = null;

            var requestData = context.ToHttpRequestData(null);

            var result = SignInCommand.Run(
                null,
                redirectUri,
                requestData,
                options,
                properties.Items);

            result.Apply(context, dataProtector, scheme.Name);

            return Task.CompletedTask;
        }
        public async Task <IActionResult> SignIn(string provider, string redirectUrl)
        {
            // Note: the "provider" parameter corresponds to the external
            // authentication provider choosen by the user agent.
            if (string.IsNullOrWhiteSpace(provider))
            {
                return(BadRequest());
            }

            if (!await HttpContext.IsProviderSupportedAsync(provider))
            {
                return(BadRequest());
            }

            string url = $"{Request.Scheme}://{Request.Host}{Request.PathBase}{Request.Path}-callback?provider={provider}" + $"&redirectUrl={redirectUrl}";

            _logger.LogInformation($"SignIn-url:{url}");
            var properties = new AuthenticationProperties {
                RedirectUri = url
            };

            properties.Items[LoginProviderKey] = provider;
            return(Challenge(properties, provider));
        }
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            if (!context.OwinContext.Response.Headers.ContainsKey("Access-Control-Allow-Origin"))
            {
                context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
            }

            var user = new UserService().GetIdentityUserByLogin(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "Invalid username and/or password!");
                return;
            }

            var identity = ToClaimsIdentity(context.Options.AuthenticationType, user);

            var props = new AuthenticationProperties(new Dictionary <string, string> {
                { "userName", user.UserName }
            });
            var ticket = new AuthenticationTicket(identity, props);

            context.Validated(ticket);
        }
Beispiel #37
0
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = context.OwinContext.GetUserManager <ApplicationUserManager>();

            ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "Имя пользователя или пароль указаны неправильно.");
                return;
            }

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

            ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
                                                                                  CookieAuthenticationDefaults.AuthenticationType);

            AuthenticationProperties properties = CreateProperties(user.UserName);
            AuthenticationTicket     ticket     = new AuthenticationTicket(oAuthIdentity, properties);

            context.Validated(ticket);
            context.Request.Context.Authentication.SignIn(cookiesIdentity);
        }
Beispiel #38
0
        public async Task <IActionResult> Register(string client_assertion)
        {
            // Tell the AAD B2C middleware to invoke a specific policy.
            // NOTE: this resets the scope and response type so no authorization code is requested from this flow,
            // see https://github.com/aspnet/AspNetCore/blob/release/3.1/src/Azure/AzureAD/Authentication.AzureADB2C.UI/src/AzureAdB2COpenIDConnectEventHandlers.cs#L35-L36.
            var authenticationProperties = new AuthenticationProperties();

            authenticationProperties.RedirectUri = Url.Action("Registered", "Account");

            if (!string.IsNullOrWhiteSpace(client_assertion))
            {
                // Use the client assertion flow and pass the client_assertion through.
                authenticationProperties.Items[AzureADB2CDefaults.PolicyKey] = this.invitationClientAssertionPolicyId;
                authenticationProperties.Items[OpenIdConnectParameterNames.ClientAssertion] = client_assertion;
            }
            else
            {
                // Use the invitation code flow.
                authenticationProperties.Items[AzureADB2CDefaults.PolicyKey] = this.invitationCodePolicyId;
            }
            await HttpContext.ChallengeAsync(AzureADB2CDefaults.AuthenticationScheme, authenticationProperties);

            return(new EmptyResult());
        }
Beispiel #39
0
    public async Task ExecuteAsync_InvokesSignOutAsyncOnAllConfiguredSchemes()
    {
        // Arrange
        var authProperties = new AuthenticationProperties();
        var httpContext    = new Mock <HttpContext>();
        var auth           = new Mock <IAuthenticationService>();

        auth
        .Setup(c => c.SignOutAsync(httpContext.Object, "Scheme1", authProperties))
        .Returns(Task.CompletedTask)
        .Verifiable();
        auth
        .Setup(c => c.SignOutAsync(httpContext.Object, "Scheme2", authProperties))
        .Returns(Task.CompletedTask)
        .Verifiable();
        httpContext.Setup(c => c.RequestServices).Returns(CreateServices(auth.Object));
        var result = new SignOutResult(new[] { "Scheme1", "Scheme2" }, authProperties);

        // Act
        await((IResult)result).ExecuteAsync(httpContext.Object);

        // Assert
        auth.Verify();
    }
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            using (UserManager <IdentityUser> userManager = _userManagerFactory())
            {
                IdentityUser user = await userManager.FindAsync(context.UserName, context.Password);

                if (user == null)
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }

                ClaimsIdentity oAuthIdentity = await userManager.CreateIdentityAsync(user,
                                                                                     context.Options.AuthenticationType);

                ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user,
                                                                                       CookieAuthenticationDefaults.AuthenticationType);

                AuthenticationProperties properties = CreateProperties(user.UserName);
                AuthenticationTicket     ticket     = new AuthenticationTicket(oAuthIdentity, properties);
                context.Validated(ticket);
                context.Request.Context.Authentication.SignIn(cookiesIdentity);
            }
        }
Beispiel #41
0
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = HttpContext.Current.GetOwinContext().GetUserManager <INAB.ApplicationUserManager>();

            AppUser user = await userManager.FindAsync(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }

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

            ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
                                                                                  CookieAuthenticationDefaults.AuthenticationType);

            AuthenticationProperties properties = CreateProperties(oAuthIdentity);
            AuthenticationTicket     ticket     = new AuthenticationTicket(oAuthIdentity, properties);

            context.Validated(ticket);
            context.Request.Context.Authentication.SignIn(cookiesIdentity);
        }
Beispiel #42
0
        protected override async Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            AuthenticationProperties properties = null;

            try
            {
                string state = null;
                string code  = null;

                IReadableStringCollection query = Request.Query;
                IList <string>            values;

                values = query.GetValues("state");
                if (values != null && values.Count == 1)
                {
                    state = values[0];
                }
                properties = Options.StateDataFormat.Unprotect(state);
                if (properties == null)
                {
                    return(null);
                }

                values = query.GetValues("error");
                if (values != null && values.Count == 1)
                {
                    return(new AuthenticationTicket(null, properties));
                }

                values = query.GetValues("code");
                if (values != null && values.Count == 1)
                {
                    code = values[0];
                }

                // OAuth2 10.12 CSRF
                if (!ValidateCorrelationId(properties, _logger))
                {
                    return(new AuthenticationTicket(null, properties));
                }

                string requestPrefix = Request.Scheme + "://" + Request.Host;
                string redirectUri   = requestPrefix + Request.PathBase + Options.CallbackPath;

                var body = new List <KeyValuePair <string, string> >
                {
                    new KeyValuePair <string, string>("grant_type", "authorization_code"),
                    new KeyValuePair <string, string>("code", code),
                    new KeyValuePair <string, string>("client_id", Options.ClientId),
                    new KeyValuePair <string, string>("client_secret", Options.ClientSecret),
                    new KeyValuePair <string, string>("redirect_uri", redirectUri)
                };

                // Request the token
                var tokenResponse = await _httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body));

                tokenResponse.EnsureSuccessStatusCode();
                string content = await tokenResponse.Content.ReadAsStringAsync();

                // Deserializes the token response
                var    response    = JsonConvert.DeserializeObject <JObject>(content);
                string accessToken = response.Value <string>("access_token");

                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                var userResponse = await _httpClient.GetAsync(UserInfoEndpoint);

                var userContent = await userResponse.Content.ReadAsStringAsync();

                JObject userJson = null;
                if (userResponse.IsSuccessStatusCode)
                {
                    userJson = JObject.Parse(userContent);
                }

                var context = new IntercomAuthenticatedContext(Context, accessToken, userJson);
                context.Identity = new ClaimsIdentity(
                    Options.AuthenticationType,
                    ClaimsIdentity.DefaultNameClaimType,
                    ClaimsIdentity.DefaultRoleClaimType);

                if (!String.IsNullOrEmpty(context.UserId))
                {
                    context.Identity.AddClaim(
                        new Claim(ClaimTypes.NameIdentifier, context.UserId, XmlSchemaString, Options.AuthenticationType));
                }
                if (!String.IsNullOrEmpty(context.Email))
                {
                    context.Identity.AddClaim(
                        new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType));
                }
                context.Properties = properties;

                await Options.Provider.Authenticated(context);

                return(new AuthenticationTicket(context.Identity, context.Properties));
            }
            catch (Exception ex)
            {
                _logger.WriteError("Authentication failed", ex);
                return(new AuthenticationTicket(null, properties));
            }
        }
Beispiel #43
0
 protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
 {
     Response.ContentType = "application/json";
     Response.StatusCode  = StatusCodes.Status403Forbidden;
     await Response.WriteAsync(JsonConvert.SerializeObject((new ApiResponse(StatusCode.CODE403)).MessageModel));
 }
 private void ProcessLoginCallbackForSaml2p(AuthenticateResult externalResult, List <Claim> localClaims, AuthenticationProperties localSignInProps)
 {
 }
        public async Task <IActionResult> Callback()
        {
            // read external identity from the temporary cookie
            var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);

            if (result?.Succeeded != true)
            {
                throw new Exception("External authentication error");
            }

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}");
                _logger.LogDebug("External claims: {@claims}", externalClaims);
            }

            // lookup our user and external provider info
            var(user, provider, providerUserId, claims) = await FindUserFromExternalProviderAsync(result);

            if (user == null)
            {
                // this might be where you might initiate a custom workflow for user registration
                // in this sample we don't show how that would be done, as our sample implementation
                // simply auto-provisions new external user
                user = await AutoProvisionUserAsync(provider, providerUserId, claims);
            }

            // this allows us to collect any additonal claims or properties
            // for the specific prtotocols used and store them in the local auth cookie.
            // this is typically used to store data needed for signout from those protocols.
            var additionalLocalClaims = new List <Claim>();
            var localSignInProps      = new AuthenticationProperties();

            ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps);
            ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps);
            ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps);

            // issue authentication cookie for user
            // we must issue the cookie maually, and can't use the SignInManager because
            // it doesn't expose an API to issue additional claims from the login workflow
            var principal = await _signInManager.CreateUserPrincipalAsync(user);

            additionalLocalClaims.AddRange(principal.Claims);
            var name = principal.FindFirst(JwtClaimTypes.Name)?.Value ?? user.Id;
            await HttpContext.SignInAsync(user.Id, name, provider, localSignInProps, additionalLocalClaims.ToArray());

            // delete temporary cookie used during external authentication
            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

            // retrieve return URL
            var returnUrl = result.Properties.Items["returnUrl"] ?? "~/";

            // check if external login is in the context of an OIDC request
            var context = await _interaction.GetAuthorizationContextAsync(returnUrl);

            await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, name, true, context?.ClientId));

            if (context != null)
            {
                if (await _clientStore.IsPkceClientAsync(context.ClientId))
                {
                    // if the client is PKCE then we assume it's native, so this change in how to
                    // return the response is for better UX for the end user.
                    return(View("Redirect", new RedirectViewModel {
                        RedirectUrl = returnUrl
                    }));
                }
            }

            return(Redirect(returnUrl));
        }
        /// <summary>
        /// Handles the <see cref="MsalUiRequiredException"/>.
        /// </summary>
        /// <param name="context">Context provided by ASP.NET Core.</param>
        public override void OnException(ExceptionContext context)
        {
            if (context != null)
            {
                MsalUiRequiredException?msalUiRequiredException = FindMsalUiRequiredExceptionIfAny(context.Exception);
                if (msalUiRequiredException != null &&
                    IncrementalConsentAndConditionalAccessHelper.CanBeSolvedByReSignInOfUser(msalUiRequiredException))
                {
                    // the users cannot provide both scopes and ScopeKeySection at the same time
                    if (!string.IsNullOrWhiteSpace(ScopeKeySection) && Scopes != null && Scopes.Length > 0)
                    {
                        throw new InvalidOperationException(
                                  string.Format(
                                      CultureInfo.InvariantCulture,
                                      IDWebErrorMessage.ProvideEitherScopeKeySectionOrScopes,
                                      nameof(ScopeKeySection),
                                      nameof(Scopes)));
                    }

                    // Do not re-use the property Scopes. For more info: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/issues/273
                    string[]? incrementalConsentScopes;

                    // If the user wishes us to pick the Scopes from a particular config setting.
                    if (!string.IsNullOrWhiteSpace(ScopeKeySection))
                    {
                        // Load the injected IConfiguration
                        IConfiguration?configuration = context.HttpContext.RequestServices.GetService <IConfiguration>();

                        if (configuration == null)
                        {
                            throw new InvalidOperationException(
                                      string.Format(
                                          CultureInfo.InvariantCulture,
                                          IDWebErrorMessage.ScopeKeySectionIsProvidedButNotPresentInTheServicesCollection,
                                          nameof(ScopeKeySection)));
                        }

                        incrementalConsentScopes = new string[] { configuration.GetValue <string>(ScopeKeySection) };

                        if (Scopes != null && Scopes.Length > 0 && incrementalConsentScopes.Length > 0)
                        {
                            throw new InvalidOperationException(IDWebErrorMessage.NoScopesProvided);
                        }
                    }
                    else
                    {
                        incrementalConsentScopes = Scopes;
                    }

                    HttpRequest     httpRequest;
                    ClaimsPrincipal user;
                    HttpContext     httpContext = context.HttpContext;

                    lock (httpContext)
                    {
                        httpRequest = httpContext.Request;
                        user        = httpContext.User;
                    }

                    AuthenticationProperties properties = IncrementalConsentAndConditionalAccessHelper.BuildAuthenticationProperties(
                        incrementalConsentScopes,
                        msalUiRequiredException,
                        user,
                        UserFlow);

                    if (IsAjaxRequest(httpRequest) && (!string.IsNullOrEmpty(httpRequest.Headers[Constants.XReturnUrl]) ||
                                                       !string.IsNullOrEmpty(httpRequest.Query[Constants.XReturnUrl])))
                    {
                        string redirectUri = !string.IsNullOrEmpty(httpRequest.Headers[Constants.XReturnUrl]) ? httpRequest.Headers[Constants.XReturnUrl]
                            : httpRequest.Query[Constants.XReturnUrl];

                        UrlHelper urlHelper = new UrlHelper(context);
                        if (urlHelper.IsLocalUrl(redirectUri))
                        {
                            properties.RedirectUri = redirectUri;
                        }
                    }

                    if (AuthenticationScheme != null)
                    {
                        context.Result = new ChallengeResult(AuthenticationScheme, properties);
                    }
                    else
                    {
                        context.Result = new ChallengeResult(properties);
                    }
                }
            }

            base.OnException(context);
        }
Beispiel #47
0
        protected virtual async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
        {
            using (var user = JsonDocument.Parse("{}"))
            {
                var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, user.RootElement);
                await Events.CreatingTicket(context);

                return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));
            }
        }
 public Task ForbidAsync(AuthenticationProperties properties)
 {
     Context.Response.StatusCode = 403;
     return(Task.CompletedTask);
 }
Beispiel #49
0
        protected override async Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            AuthenticationProperties properties = null;

            try
            {
                string code  = null;
                string state = null;

                var query  = Request.Query;
                var values = query.GetValues("code");
                if (values != null && values.Count == 1)
                {
                    code = values[0];
                }
                values = query.GetValues("state");
                if (values != null && values.Count == 1)
                {
                    state = values[0];
                }

                properties = Options.StateDataFormat.Unprotect(state);
                if (properties == null)
                {
                    return(null);
                }

                // OAuth2 10.12 CSRF
                if (!ValidateCorrelationId(properties, _logger))
                {
                    return(new AuthenticationTicket(null, properties));
                }

                var requestPrefix = Request.Scheme + "://" + this.GetHostName();
                var redirectUri   = requestPrefix + Request.PathBase + Options.CallbackPath;

                // Build up the body for the token request
                var body = new List <KeyValuePair <string, string> >
                {
                    new KeyValuePair <string, string>("grant_type", "authorization_code"),
                    new KeyValuePair <string, string>("code", code),
                    new KeyValuePair <string, string>("redirect_uri", redirectUri),
                    new KeyValuePair <string, string>("client_id", Options.ClientId),
                    new KeyValuePair <string, string>("client_secret", Options.ClientSecret)
                };

                // Request the token
                var tokenResponse = await _httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body));

                tokenResponse.EnsureSuccessStatusCode();
                var text = await tokenResponse.Content.ReadAsStringAsync();

                // Deserializes the token response
                dynamic response    = JsonConvert.DeserializeObject <dynamic>(text);
                var     accessToken = (string)response.access_token;
                var     expires     = (string)response.expires_in;

                // Get the LinkedIn user
                var userInfoEndpoint = UserInfoEndpoint
                                       + "~:(" + string.Join(",", Options.ProfileFields.Distinct().ToArray()) + ")"
                                       + "?oauth2_access_token=" + Uri.EscapeDataString(accessToken);
                var userRequest = new HttpRequestMessage(HttpMethod.Get, userInfoEndpoint);
                userRequest.Headers.Add("x-li-format", "json");
                var graphResponse = await _httpClient.SendAsync(userRequest, Request.CallCancelled);

                graphResponse.EnsureSuccessStatusCode();
                text = await graphResponse.Content.ReadAsStringAsync();

                var user = JObject.Parse(text);

                var context = new LinkedInAuthenticatedContext(Context, user, accessToken, expires)
                {
                    Identity = new ClaimsIdentity(
                        Options.AuthenticationType,
                        ClaimsIdentity.DefaultNameClaimType,
                        ClaimsIdentity.DefaultRoleClaimType)
                };
                if (!string.IsNullOrEmpty(context.Id))
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Email))
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.GivenName))
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.FamilyName))
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Name))
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, XmlSchemaString, Options.AuthenticationType));
                    context.Identity.AddClaim(new Claim("urn:linkedin:name", context.Name, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Industry))
                {
                    context.Identity.AddClaim(new Claim("urn:linkedin:industry", context.Industry, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Positions))
                {
                    context.Identity.AddClaim(new Claim("urn:linkedin:positions", context.Positions, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Summary))
                {
                    context.Identity.AddClaim(new Claim("urn:linkedin:summary", context.Summary, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Headline))
                {
                    context.Identity.AddClaim(new Claim("urn:linkedin:headline", context.Headline, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Link))
                {
                    context.Identity.AddClaim(new Claim("urn:linkedin:url", context.Link, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.AccessToken))
                {
                    context.Identity.AddClaim(new Claim("urn:linkedin:accesstoken", context.AccessToken, XmlSchemaString, Options.AuthenticationType));
                }
                context.Properties = properties;

                await Options.Provider.Authenticated(context);

                return(new AuthenticationTicket(context.Identity, context.Properties));
            }
            catch (Exception ex)
            {
                _logger.WriteError(ex.Message);
            }
            return(new AuthenticationTicket(null, properties));
        }
        /// <summary>
        /// The core authentication logic which must be provided by the handler. Will be invoked at most
        /// once per request. Do not call directly, call the wrapping Authenticate method instead.
        /// </summary>
        /// <returns>The ticket data provided by the authentication logic.</returns>
        protected override async Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            if (!this.ShouldAuthenticate())
            {
                return(null);
            }

            try
            {
                var query = this.Request.Query;

                // Try to refresh token if a cookie exists
                if (this.Context.Authentication.User != null && !this.Context.Authentication.User.Identity.IsAuthenticated)
                {
                    var refreshCookie = this.Context.Request.Cookies.FirstOrDefault(x => x.Key == $"{this.Options.CookieConfiguration.Name}_RT");

                    if (refreshCookie.Value != null)
                    {
                        var refreshTokenResponse = await this.Options.TicketHandler.RefreshTokenAsync(this.Context, this.Options, refreshCookie.Value, this.Options.RedirectUri);

                        if (refreshTokenResponse != null)
                        {
                            // Sign in as sentinel identity
                            var props = new AuthenticationProperties()
                            {
                                RedirectUri = this.Context.Request.Uri.ToString()
                            };
                            var ticket = await this.Options.TicketHandler.SignInAsync(this.Context, this.Options, refreshTokenResponse, props);

                            await this.Options.Events.OnTokenRefreshed(this.Context, ticket, this.Options);

                            return(ticket);
                        }

                        this.Options.Logger.WriteError("Refresh token found, but was unable to use it to retrieve a new access token");

                        // Delete refresh token if it didnt work to prevent retries with an invalid token
                        this.Context.Response.Cookies.Delete($"{this.Options.CookieConfiguration.Name}_RT", new CookieOptions()
                        {
                            Domain = this.Request.Uri.Host, Secure = this.Request.IsSecure
                        });
                    }
                }

                // Check for errors
                var error = query["error"];
                if (!string.IsNullOrEmpty(error))
                {
                    var failureMessage = new StringBuilder();
                    failureMessage.Append(error);
                    var errorDescription = query["error_description"];
                    if (!string.IsNullOrEmpty(errorDescription))
                    {
                        failureMessage.Append(";Description=").Append(errorDescription);
                    }
                    var errorUri = query["error_uri"];
                    if (!string.IsNullOrEmpty(errorUri))
                    {
                        failureMessage.Append(";Uri=").Append(errorUri);
                    }

                    this.Options.Logger.WriteError(failureMessage.ToString());

                    await this.Options.Events.OnAuthorizeError(this.Context, this.Options, error, errorDescription, errorUri);

                    return(null);
                }

                string code  = null;
                string state = null;

                // Parse code
                var codeQueryParam = query.GetValues("code");
                if (codeQueryParam != null && codeQueryParam.Count == 1)
                {
                    code = codeQueryParam[0];
                }

                // Parse state
                var stateQueryParam = query.GetValues("state");
                if (stateQueryParam != null && stateQueryParam.Count == 1)
                {
                    state = stateQueryParam[0];
                }

                // Dont continue if code is null
                if (string.IsNullOrEmpty(code))
                {
                    return(null);
                }

                // Extract state
                var properties = this.Options.StateDataFormat.Unprotect(state);

                if (properties == null)
                {
                    await this.Options.Events.OnStateError(this.Context, this.Options, properties, "invalid_state");

                    return(null);
                }

                // Validate state to prevent CSRF (See https://tools.ietf.org/html/rfc6749#section-10.12)
                if (!this.ValidateCorrelationId(properties, this.Options.Logger))
                {
                    this.Options.Logger.WriteError("The CSRF Correlation ID is invalid");

                    await this.Options.Events.OnStateError(this.Context, this.Options, properties, "invalid_correlation_id");

                    return(null);
                }

                var tokenResponse = await this.Options.TicketHandler.ExchangeCodeAsync(this.Context, this.Options, code, this.Options.RedirectUri);

                if (string.IsNullOrEmpty(tokenResponse.AccessToken))
                {
                    this.Options.Logger.WriteError("No access token was included in the response");

                    await this.Options.Events.OnTokenError(this.Context, this.Options, tokenResponse);

                    return(null);
                }

                return(await this.Options.TicketHandler.SignInAsync(this.Context, this.Options, tokenResponse, properties));
            }
            catch (Exception ex)
            {
                this.Options.Logger.WriteError("Authentication failed", ex);

                await this.Options.Events.OnException(this.Context, this.Options, ex);

                return(null);
            }
        }
 public Task ChallengeAsync(AuthenticationProperties properties)
 {
     Context.Response.Redirect("/login");
     return(Task.CompletedTask);
 }
Beispiel #52
0
        private void ProcessLoginCallbackForOidc(AuthenticateResult externalResult, List <Claim> localClaims, AuthenticationProperties localSignInProps)
        {
            // if the external system sent a session id claim, copy it over
            // so we can use it for single sign-out
            var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);

            if (sid != null)
            {
                localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));
            }

            // if the external provider issued an id_token, we'll keep it for signout
            var id_token = externalResult.Properties.GetTokenValue("id_token");

            if (id_token != null)
            {
                localSignInProps.StoreTokens(new[] { new AuthenticationToken {
                                                         Name = "id_token", Value = id_token
                                                     } });
            }
        }
Beispiel #53
0
 /// <summary>
 /// This is called when a Challenge is issued to this authentication schema
 /// </summary>
 /// <param name="properties">These are not used in this middleware</param>
 /// <returns>A completed task to indicate that the challenge was handled</returns>
 protected override Task HandleChallengeAsync(AuthenticationProperties properties)
 {
     Logger.LogInformation("Challenge started");
     Response.Redirect(Options.CallbackPath);
     return(Task.CompletedTask);
 }
        /// <summary>Gets the <see cref="ImgurAuthenticatedContext"/> for the current authentication session.</summary>
        /// <param name="authenticationResponse">The <see cref="AuthenticationResponse"/> returned by imgur.</param>
        /// <param name="identity">The <see cref="ClaimsIdentity"/> for the identity of the user.</param>
        /// <param name="properties">The <see cref="AuthenticationProperties"/> for the current authentication session.</param>
        /// <returns>The <see cref="ImgurAuthenticatedContext"/> for the current authentication session.</returns>
        private ImgurAuthenticatedContext GetImgurAuthenticatedContext(AuthenticationResponse authenticationResponse, ClaimsIdentity identity, AuthenticationProperties properties)
        {
            var context = new ImgurAuthenticatedContext(this.Context, this.Options);

            context.AccessToken     = authenticationResponse.AccessToken;
            context.AccountId       = authenticationResponse.AccountId;
            context.AccountUsername = authenticationResponse.AccountUsername;
            context.ExpiresIn       = authenticationResponse.ExpiresIn;
            context.Identity        = identity;
            context.Properties      = properties;
            context.RefreshToken    = authenticationResponse.RefreshToken;
            context.Scope           = authenticationResponse.Scope;
            context.TokenType       = authenticationResponse.TokenType;

            return(context);
        }
Beispiel #55
0
 /// <summary>
 /// Creates a <see cref="TokenValidatedContext"/>
 /// </summary>
 public TokenValidatedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, ClaimsPrincipal principal, AuthenticationProperties properties)
     : base(context, scheme, options, properties)
     => Principal = principal;
Beispiel #56
0
        //public AuthenticationTicket Unprotect(string protectedText)
        //{
        //    throw new NotImplementedException();
        //    //return new AuthenticationTicket(identity, authenticationProperties);
        //}

        /// <summary>
        ///  method which is responsible for validation of the JWT and returning and authentication ticket:
        /// </summary>
        /// <param name = "protectedText" ></ param >
        /// < returns ></ returns >
        public AuthenticationTicket Unprotect(string protectedText)
        {
            Microsoft.IdentityModel.Tokens.SecurityToken validatedToken;
            if (string.IsNullOrWhiteSpace(protectedText))
            {
                throw new ArgumentNullException("protectedText");
            }
            //Fwk.Security.Identity.jwtSecurityProvider sec_provider = null;

            var tokenHandler              = new JwtSecurityTokenHandler();
            var jwtSecurityToken          = tokenHandler.ReadJwtToken(protectedText);
            var securityProviderNameClaim = jwtSecurityToken.Claims.FirstOrDefault(c => c.Type == "securityProviderName");

            if (securityProviderNameClaim == null)
            {
                throw new ArgumentNullException("securityProviderName claims in jwt");
            }

            var sec_provider = helper.get_secConfig().GetByName(securityProviderNameClaim.Value);

            if (sec_provider == null)
            {
                throw new ArgumentNullException("No se encuentra configurado el proveedor (securityProviderName) en securityConfig.json");
            }
            string audienceId           = sec_provider.audienceId;
            string symmetricKeyAsBase64 = sec_provider.audienceSecret;
            var    keyByteArray         = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);

            var securityKey        = new SymmetricSecurityKey(keyByteArray);
            var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);



            //TODO : CustomJwtFormat Esta lista de issuers debe ser flexible
            ///Establezco los issuers validos
            var issuers = new List <string>()
            {
                "http://localhost:44345/"
            };

            var validationParams = new TokenValidationParameters()
            {
                ValidAudience            = sec_provider.audienceId,
                ValidIssuers             = issuers,
                ValidateLifetime         = true,
                ValidateAudience         = true,
                ValidateIssuer           = true,
                RequireSignedTokens      = true,
                RequireExpirationTime    = true,
                ValidateIssuerSigningKey = true,
                ClockSkew = TimeSpan.Zero,
                //IssuerSigningKeys = DefaultX509Key_Public_2048
                IssuerSigningKey = signingCredentials.Key
            };

            try
            {
                var principal = tokenHandler.ValidateToken(protectedText, validationParams, out validatedToken);


                var identity = principal.Identities.First();

                // Fill out the authenticationProperties issued and expires times if the equivalent claims are in the JWT
                var authenticationProperties = new AuthenticationProperties();

                //issued
                if (validatedToken.ValidFrom != DateTime.MinValue)
                {
                    authenticationProperties.IssuedUtc = validatedToken.ValidFrom.ToUniversalTime();
                }
                //expires
                if (validatedToken.ValidTo != DateTime.MinValue)
                {
                    authenticationProperties.ExpiresUtc = validatedToken.ValidTo.ToUniversalTime();
                }

                return(new AuthenticationTicket(identity, authenticationProperties));
            }
            catch (Exception ex)
            {
                //var statusCode = HttpStatusCode.Unauthorized;
                //return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode) { });
                var ec = new Fwk.Exceptions.FunctionalException((int)HttpStatusCode.Unauthorized, " No autorizado ", ex);
                throw ec;
            }
        }
Beispiel #57
0
        public async Task <IActionResult> Callback()
        {
            // read external identity from the temporary cookie
            var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);

            if (result?.Succeeded != true)
            {
                throw new Exception("External authentication error");
            }

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}");
                _logger.LogDebug("External claims: {@claims}", externalClaims);
            }

            // lookup our user and external provider info
            var(user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);
            if (user == null)
            {
                // this might be where you might initiate a custom workflow for user registration
                // in this sample we don't show how that would be done, as our sample implementation
                // simply auto-provisions new external user
                user = AutoProvisionUser(provider, providerUserId, claims);
            }

            // this allows us to collect any additional claims or properties
            // for the specific protocols used and store them in the local auth cookie.
            // this is typically used to store data needed for signout from those protocols.
            var additionalLocalClaims = new List <Claim>();
            var localSignInProps      = new AuthenticationProperties();

            ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps);
            //ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps);
            //ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps);

            // issue authentication cookie for user
            var isuser = new IdentityServerUser(user.SubjectId)
            {
                DisplayName      = user.Username,
                IdentityProvider = provider,
                AdditionalClaims = additionalLocalClaims
            };

            await HttpContext.SignInAsync(isuser, localSignInProps);

            // delete temporary cookie used during external authentication
            await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);

            // retrieve return URL
            var returnUrl = result.Properties.Items["returnUrl"] ?? "~/";

            // check if external login is in the context of an OIDC request
            var context = await _interaction.GetAuthorizationContextAsync(returnUrl);

            await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.ClientId));

            if (context != null)
            {
                if (await _clientStore.IsPkceClientAsync(context.ClientId))
                {
                    // if the client is PKCE then we assume it's native, so this change in how to
                    // return the response is for better UX for the end user.
                    return(this.LoadingPage("Redirect", returnUrl));
                }
            }

            return(Redirect(returnUrl));
        }
Beispiel #58
0
        public async Task <IHttpActionResult> GetExternalLogin(string provider, string error = null)
        {
            if (error != null)
            {
                return(Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error)));
            }

            if (!User.Identity.IsAuthenticated)
            {
                return(new ChallengeResult(provider, this));
            }

            ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);

            if (externalLogin == null || externalLogin.LoginProvider != provider)
            {
                Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
                return(Redirect(Url.Content("~/")));
            }

            IdentityAccount account = await _userManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, externalLogin.ProviderKey));

            if (account == null)
            {
                IdentityResult result = null;

                account = await _userManager.FindByNameAsync(externalLogin.UserName);

                if (account == null)
                {
                    account = new IdentityAccount {
                        UserName = externalLogin.UserName
                    };
                    result = await _userManager.CreateAsync(account);

                    if (!result.Succeeded)
                    {
                        return(InternalServerError());
                    }
                }

                UserLoginInfo login = new UserLoginInfo(externalLogin.LoginProvider, externalLogin.ProviderKey);
                result = await _userManager.AddLoginAsync(account.Id, login);

                if (!result.Succeeded)
                {
                    return(InternalServerError());
                }
            }

            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            ClaimsIdentity oAuthIdentity = await _userManager.CreateIdentityAsync(account,
                                                                                  OAuthDefaults.AuthenticationType);

            ClaimsIdentity cookieIdentity = await _userManager.CreateIdentityAsync(account,
                                                                                   CookieAuthenticationDefaults.AuthenticationType);

            AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(account.UserName);

            Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);

            return(Ok());
        }
Beispiel #59
0
        public async Task <IActionResult> Login(LoginInputModel model, string button)
        {
            // check if we are in the context of an authorization request
            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

            // the user clicked the "cancel" button
            if (button != "login")
            {
                if (context != null)
                {
                    // if the user cancels, send a result back into IdentityServer as if they
                    // denied the consent (even if this client does not require consent).
                    // this will send back an access denied OIDC error response to the client.
                    await _interaction.GrantConsentAsync(context, ConsentResponse.Denied);

                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
                    if (await _clientStore.IsPkceClientAsync(context.ClientId))
                    {
                        // if the client is PKCE then we assume it's native, so this change in how to
                        // return the response is for better UX for the end user.
                        return(View("Redirect", new RedirectViewModel {
                            RedirectUrl = model.ReturnUrl
                        }));
                    }

                    return(Redirect(model.ReturnUrl));
                }
                else
                {
                    // since we don't have a valid context, then we just go back to the home page
                    return(Redirect("~/"));
                }
            }

            if (ModelState.IsValid)
            {
                // validate username/password against in-memory store
                if (_users.ValidateCredentials(model.Username, model.Password))
                {
                    var user = _users.FindByUsername(model.Username);
                    await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId : context?.ClientId));

                    // only set explicit expiration here if user chooses "remember me".
                    // otherwise we rely upon expiration configured in cookie middleware.
                    AuthenticationProperties props = null;
                    if (AccountOptions.AllowRememberLogin && model.RememberLogin)
                    {
                        props = new AuthenticationProperties
                        {
                            IsPersistent = true,
                            ExpiresUtc   = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)
                        };
                    }
                    ;

                    // issue authentication cookie with subject ID and username
                    await HttpContext.SignInAsync(user.SubjectId, user.Username, props);

                    if (context != null)
                    {
                        if (await _clientStore.IsPkceClientAsync(context.ClientId))
                        {
                            // if the client is PKCE then we assume it's native, so this change in how to
                            // return the response is for better UX for the end user.
                            return(View("Redirect", new RedirectViewModel {
                                RedirectUrl = model.ReturnUrl
                            }));
                        }

                        // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
                        return(Redirect(model.ReturnUrl));
                    }

                    // request for a local page
                    if (Url.IsLocalUrl(model.ReturnUrl))
                    {
                        return(Redirect(model.ReturnUrl));
                    }
                    else if (string.IsNullOrEmpty(model.ReturnUrl))
                    {
                        return(Redirect("~/"));
                    }
                    else
                    {
                        // user might have clicked on a malicious link - should be logged
                        throw new Exception("invalid return URL");
                    }
                }

                await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId : context?.ClientId));

                ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);
            }

            // something went wrong, show form with error
            var vm = await BuildLoginViewModelAsync(model);

            return(View(vm));
        }
Beispiel #60
0
        protected override async Task <AuthenticationTicket> CreateTicketAsync(
            [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties,
            [NotNull] string identifier, [NotNull] IReadOnlyDictionary <string, string> attributes)
        {
            var principal = new ClaimsPrincipal(identity);
            var ticket    = new AuthenticationTicket(principal, properties, Scheme.Name);

            // Return the authentication ticket as-is if the user information endpoint has not been set.
            if (string.IsNullOrEmpty(Options.UserInformationEndpoint))
            {
                Logger.LogInformation("The userinfo request was skipped because no userinfo endpoint was configured.");

                return(await RunAuthenticatedEventAsync());
            }

            // Return the authentication ticket as-is if the application key has not been set.
            if (string.IsNullOrEmpty(Options.ApplicationKey))
            {
                Logger.LogInformation("The userinfo request was skipped because no application key was configured.");

                return(await RunAuthenticatedEventAsync());
            }

            // Note: prior to April 2018, the Steam identifier was prefixed with an HTTP base address.
            // Since then, the prefix is now an HTTPS address. The following logic supports both prefixes.
            if (identifier.StartsWith(SteamAuthenticationConstants.Namespaces.Identifier, StringComparison.Ordinal))
            {
                identifier = identifier.Substring(SteamAuthenticationConstants.Namespaces.Identifier.Length);
            }

            else if (identifier.StartsWith(SteamAuthenticationConstants.Namespaces.LegacyIdentifier, StringComparison.Ordinal))
            {
                identifier = identifier.Substring(SteamAuthenticationConstants.Namespaces.LegacyIdentifier.Length);
            }

            // Prevent the sign-in operation from completing if the claimed identifier is malformed.
            else
            {
                Logger.LogWarning("The userinfo request was skipped because an invalid identifier was received: {Identifier}.", identifier);

                throw new InvalidOperationException($"The OpenID claimed identifier '{identifier}' is not valid.");
            }

            var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string>
            {
                [SteamAuthenticationConstants.Parameters.Key]     = Options.ApplicationKey,
                [SteamAuthenticationConstants.Parameters.SteamId] = identifier
            });

            var request = new HttpRequestMessage(HttpMethod.Get, address);

            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(OpenIdAuthenticationConstants.Media.Json));

            // Return the authentication ticket as-is if the userinfo request failed.
            var response = await Options.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogWarning("The userinfo request failed because an invalid response was received: the identity provider " +
                                  "returned returned a {Status} response with the following payload: {Headers} {Body}.",
                                  /* Status: */ response.StatusCode,
                                  /* Headers: */ response.Headers.ToString(),
                                  /* Body: */ await response.Content.ReadAsStringAsync());

                throw new HttpRequestException("An error occurred while retrieving the user profile from Steam.");
            }

            using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());

            // Try to extract the profile name of the authenticated user.
            var profile = payload.RootElement
                          .GetProperty(SteamAuthenticationConstants.Parameters.Response)
                          .GetProperty(SteamAuthenticationConstants.Parameters.Players)
                          .EnumerateArray()
                          .FirstOrDefault();

            if (profile.ValueKind == JsonValueKind.Object && profile.TryGetProperty(SteamAuthenticationConstants.Parameters.Name, out var name))
            {
                identity.AddClaim(new Claim(ClaimTypes.Name, name.GetString(), ClaimValueTypes.String, Options.ClaimsIssuer));
            }

            return(await RunAuthenticatedEventAsync(payload));

            async Task <AuthenticationTicket> RunAuthenticatedEventAsync(JsonDocument user = null)
            {
                var context = new OpenIdAuthenticatedContext(Context, Scheme, Options, ticket)
                {
                    UserPayload = user
                };

                if (user != null)
                {
#pragma warning disable CS0618
                    context.User = JObject.Parse(user.RootElement.ToString());
#pragma warning restore CS0618
                }

                // Copy the attributes to the context object.
                foreach (var attribute in attributes)
                {
                    context.Attributes.Add(attribute);
                }

                await Events.Authenticated(context);

                // Note: return the authentication ticket associated
                // with the notification to allow replacing the ticket.
                return(context.Ticket);
            }
        }