public override void OnException(ExceptionContext context) { if (ShouldUserReauthenticate(context.Exception)) { var properties = new AuthenticationProperties(); // Set the scopes to request, including the scopes that the MSAL token provider needs. var scopesToRequest = new List <string> { OpenIdConnectScope.OpenIdProfile, OpenIdConnectScope.OfflineAccess }; if (this.Scopes != null && this.Scopes.Any()) { // Use the MSAL token provider to replace scope placeholders with their actual values from configuration. var msalTokenProvider = context.HttpContext.RequestServices.GetRequiredService <MsalTokenProvider>(); scopesToRequest.AddRange(msalTokenProvider.GetFullyQualifiedScopes(this.Scopes)); } properties.SetParameter(OpenIdConnectParameterNames.Scope, scopesToRequest); // Try to avoid displaying the "pick an account" dialog to the user if we already know who they are. properties.SetParameter(OpenIdConnectParameterNames.LoginHint, context.HttpContext.User.GetLoginHint()); properties.SetParameter(OpenIdConnectParameterNames.DomainHint, context.HttpContext.User.GetDomainHint()); context.Result = new ChallengeResult(properties); context.ExceptionHandled = true; } base.OnException(context); }
/// <summary> /// Build Authentication properties needed for an incremental consent. /// </summary> /// <param name="scopes">Scopes to request</param> /// <returns>AuthenticationProperties</returns> private AuthenticationProperties BuildAuthenticationPropertiesForIncrementalConsent(string[] scopes, MsalUiRequiredException ex) { AuthenticationProperties properties = new AuthenticationProperties(); // Set the scopes, including the scopes that ADAL.NET / MASL.NET need for the Token cache string[] additionalBuildInScopes = new string[] { "openid", "offline_access", "profile" }; properties.SetParameter <ICollection <string> >(OpenIdConnectParameterNames.Scope, scopes.Union(additionalBuildInScopes).ToList()); // Attempts to set the login_hint to avoid the logged-in user to be presented with an account selection dialog string loginHint = HttpContext.User.GetLoginHint(); if (!string.IsNullOrWhiteSpace(loginHint)) { properties.SetParameter <string>(OpenIdConnectParameterNames.LoginHint, loginHint); string domainHint = HttpContext.User.GetDomainHint(); properties.SetParameter <string>(OpenIdConnectParameterNames.DomainHint, domainHint); } // Additional claims required (for instance MFA) if (!string.IsNullOrEmpty(ex.Claims)) { properties.Items.Add("claims", ex.Claims); } return(properties); }
/// <summary> /// Build Authentication properties needed for incremental consent. /// </summary> /// <param name="scopes">Scopes to request</param> /// <param name="ex">MsalUiRequiredException instance</param> /// <param name="context">current http context in the pipeline</param> /// <returns>AuthenticationProperties</returns> private AuthenticationProperties BuildAuthenticationPropertiesForIncrementalConsent( string[] scopes, MsalUiRequiredException ex, HttpContext context) { var properties = new AuthenticationProperties(); // Set the scopes, including the scopes that ADAL.NET / MSAL.NET need for the token cache string[] additionalBuiltInScopes = { OidcConstants.ScopeOpenId, OidcConstants.ScopeOfflineAccess, OidcConstants.ScopeProfile }; properties.SetParameter <ICollection <string> >(OpenIdConnectParameterNames.Scope, scopes.Union(additionalBuiltInScopes).ToList()); // Attempts to set the login_hint to avoid the logged-in user to be presented with an account selection dialog var loginHint = context.User.GetLoginHint(); if (!string.IsNullOrWhiteSpace(loginHint)) { properties.SetParameter(OpenIdConnectParameterNames.LoginHint, loginHint); var domainHint = context.User.GetDomainHint(); properties.SetParameter(OpenIdConnectParameterNames.DomainHint, domainHint); } // Additional claims required (for instance MFA) if (!string.IsNullOrEmpty(ex.Claims)) { properties.Items.Add(OidcConstants.AdditionalClaims, ex.Claims); } return(properties); }
protected override async Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties) { if (user == null) { throw new ArgumentNullException(nameof(user)); } properties = properties ?? new AuthenticationProperties(); if (Options.ValidateIssuer) { if (string.IsNullOrWhiteSpace(properties.GetParameter <string>(CookignConstants.Issuer))) { properties.SetParameter(CookignConstants.Issuer, Options.CookingSettings.Issuer); } } if (Options.ValidateAudience) { if (string.IsNullOrWhiteSpace(properties.GetParameter <string>(CookignConstants.Audience))) { properties.SetParameter(CookignConstants.Audience, Options.CookingSettings.Audience); } } if (Options.ValidateIpPublic) { if (properties.GetParameter <IPAddress>(CookignConstants.RemoteIp) == null) { properties.SetParameter(CookignConstants.RemoteIp, Context.Connection.RemoteIpAddress); } } AuthenticationTicket ticket = new AuthenticationTicket(user, properties, Scheme.Name); string valueCookie = CreateProtector().Protect(ticket); CookieOptions options = new CookieOptions { HttpOnly = Options.HttpOnly, SameSite = Options.SameSiteMode, Secure = Options.Secure, Expires = DateTime.Now + Options.ExpireTimeSpan }; Response.Cookies.Append(Options.CookieTokenName, valueCookie, options); if (Options.CreateCookieClaims) { options = new CookieOptions { Expires = DateTime.Now + Options.ExpireTimeSpan }; string claimsJson = Newtonsoft.Json.JsonConvert.SerializeObject(from c in user.Claims select new { c.Type, c.Value }); string cookieClaimValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(claimsJson)); Response.Cookies.Append(Options.CookieClaimsName, cookieClaimValue, options); } }
/// <summary> /// Build authentication properties needed for incremental consent. /// </summary> /// <param name="scopes">Scopes to request.</param> /// <param name="ex"><see cref="MsalUiRequiredException"/> instance.</param> /// <param name="user">User.</param> /// <param name="userflow">Userflow being invoked for AAD B2C.</param> /// <returns>AuthenticationProperties.</returns> public static AuthenticationProperties BuildAuthenticationProperties( string[]?scopes, MsalUiRequiredException ex, ClaimsPrincipal user, string?userflow = null) { if (ex == null) { throw new ArgumentNullException(nameof(ex)); } scopes ??= new string[0]; var properties = new AuthenticationProperties(); // Set the scopes, including the scopes that MSAL.NET needs for the token cache string[] additionalBuiltInScopes = { OidcConstants.ScopeOpenId, OidcConstants.ScopeOfflineAccess, OidcConstants.ScopeProfile, }; HashSet <string> oidcParams = new HashSet <string>(scopes); oidcParams.UnionWith(additionalBuiltInScopes); properties.SetParameter(OpenIdConnectParameterNames.Scope, oidcParams.ToList()); // Attempts to set the login_hint to avoid the logged-in user to be presented with an account selection dialog var loginHint = user.GetLoginHint(); if (!string.IsNullOrWhiteSpace(loginHint)) { properties.SetParameter(OpenIdConnectParameterNames.LoginHint, loginHint); var domainHint = user.GetDomainHint(); properties.SetParameter(OpenIdConnectParameterNames.DomainHint, domainHint); } // Additional claims required (for instance MFA) if (!string.IsNullOrEmpty(ex.Claims)) { properties.Items.Add(OidcConstants.AdditionalClaims, ex.Claims); } // Include current userflow for B2C if (!string.IsNullOrEmpty(userflow)) { properties.Items.Add(OidcConstants.PolicyKey, userflow); } return(properties); }
public async Task ChallengeWillIncludeScopeAsOverwrittenWithBaseAuthenticationProperties() { using var host = await CreateHost( app => app.UseAuthentication(), services => { services.AddAuthentication().AddFacebook(o => { o.AppId = "Test App Id"; o.AppSecret = "Test App Secret"; o.Scope.Clear(); o.Scope.Add("foo"); o.Scope.Add("bar"); }); }, async context => { var properties = new AuthenticationProperties(); properties.SetParameter(OAuthChallengeProperties.ScopeKey, new string[] { "baz", "qux" }); await context.ChallengeAsync(FacebookDefaults.AuthenticationScheme, properties); return(true); }); using var server = host.GetTestServer(); var transaction = await server.SendAsync("http://example.com/challenge"); var res = transaction.Response; Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); Assert.Contains("scope=baz,qux", res.Headers.Location.Query); }
public async Task <IActionResult> HrdRedirect([FromForm] string mail) { var p = new AuthenticationProperties() { RedirectUri = "/" }; if (await IsLikelyAad(mail)) { p.SetParameter <string>("login_hint", mail); p.SetParameter <string>("domain_hint", "aad"); return(Challenge(p, OpenIdConnectDefaults.AuthenticationScheme)); } p.SetParameter <string>("login_hint", mail); return(Challenge(p, OpenIdConnectDefaults.AuthenticationScheme)); }
private AuthenticateResult Fail(CaberMutualAuthenticationFailureReason failure) { var properties = new AuthenticationProperties(); properties.SetParameter(FailureReasonEntry, failure); return(AuthenticateResult.Fail(new CaberMutualAuthenticationFailureReasonFormatter().Format(failure), properties)); }
public async Task RedirectToAuthorizeEndpoint_HasScopeAsOverwrittenWithBaseAuthenticationProperties() { using var host = await CreateHost( s => s.AddAuthentication ().AddOAuth( "Weblie", opt => { ConfigureDefaults(opt); opt.Scope.Clear(); opt.Scope.Add("foo"); opt.Scope.Add("bar"); }), async ctx => { var properties = new AuthenticationProperties(); properties.SetParameter(OAuthChallengeProperties.ScopeKey, new string[] { "baz", "qux" }); await ctx.ChallengeAsync("Weblie", properties); return(true); }); using var server = host.GetTestServer(); var transaction = await server.SendAsync("https://www.example.com/challenge"); var res = transaction.Response; Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); Assert.Contains("scope=baz%20qux", res.Headers.Location.Query); }
public async Task <IActionResult> Login(string returnUrl) { if (string.IsNullOrEmpty(returnUrl)) { returnUrl = "~/"; } if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false) { _logger.LogError($"User supplied invalid return url: {returnUrl}. Possibly a misconfiguration or malicious attempt for an attack."); return(this.RedirectToErrorPage()); } var context = await _interaction.GetAuthorizationContextAsync(returnUrl); var shouldUseMfa = context.Client.Properties.Where(p => p.Key == Insolvency.Interfaces.Constants.ShouldUseMfaKey).FirstOrDefault().Value; var props = new AuthenticationProperties { RedirectUri = Url.Action(nameof(Callback)), Items = { { "returnUrl", returnUrl }, { "scheme", Constants.ScpAuthenticationSchemeAlias } } }; if (!string.IsNullOrEmpty(shouldUseMfa)) { props.SetParameter <bool>(Insolvency.Interfaces.Constants.ShouldUseMfaKey, bool.Parse(shouldUseMfa)); } return(Challenge(props, Constants.ScpAuthenticationSchemeAlias)); }
private static TestServer CreateServer(Action <MicrosoftAccountOptions> configureOptions) { var builder = new WebHostBuilder() .Configure(app => { app.UseAuthentication(); app.Use(async(context, next) => { var req = context.Request; var res = context.Response; if (req.Path == new PathString("/challenge")) { await context.ChallengeAsync("Microsoft", new AuthenticationProperties() { RedirectUri = "/me" }); } else if (req.Path == new PathString("/challengeWithOtherScope")) { var properties = new OAuthChallengeProperties(); properties.SetScope("baz", "qux"); await context.ChallengeAsync("Microsoft", properties); } else if (req.Path == new PathString("/challengeWithOtherScopeWithBaseAuthenticationProperties")) { var properties = new AuthenticationProperties(); properties.SetParameter(OAuthChallengeProperties.ScopeKey, new string[] { "baz", "qux" }); await context.ChallengeAsync("Microsoft", properties); } else if (req.Path == new PathString("/me")) { await res.DescribeAsync(context.User); } else if (req.Path == new PathString("/signIn")) { await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignInAsync("Microsoft", new ClaimsPrincipal())); } else if (req.Path == new PathString("/signOut")) { await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignOutAsync("Microsoft")); } else if (req.Path == new PathString("/forbid")) { await Assert.ThrowsAsync <InvalidOperationException>(() => context.ForbidAsync("Microsoft")); } else { await next(); } }); }) .ConfigureServices(services => { services.AddAuthentication(TestExtensions.CookieAuthenticationScheme) .AddCookie(TestExtensions.CookieAuthenticationScheme, o => { }) .AddMicrosoftAccount(configureOptions); }); return(new TestServer(builder)); }
public void GetSetParameter_String() { var props = new AuthenticationProperties(); Assert.Null(props.GetParameter <string>("foo")); Assert.Equal(0, props.Parameters.Count); props.SetParameter <string>("foo", "foo bar"); Assert.Equal("foo bar", props.GetParameter <string>("foo")); Assert.Equal("foo bar", props.Parameters["foo"]); Assert.Equal(1, props.Parameters.Count); props.SetParameter <string>("foo", null); Assert.Null(props.GetParameter <string>("foo")); Assert.Null(props.Parameters["foo"]); Assert.Equal(1, props.Parameters.Count); }
public void GetSetParameter_Int() { var props = new AuthenticationProperties(); Assert.Null(props.GetParameter <int?>("foo")); Assert.Equal(0, props.Parameters.Count); props.SetParameter <int?>("foo", 123); Assert.Equal(123, props.GetParameter <int?>("foo")); Assert.Equal(123, props.Parameters["foo"]); Assert.Equal(1, props.Parameters.Count); props.SetParameter <int?>("foo", null); Assert.Null(props.GetParameter <int?>("foo")); Assert.Null(props.Parameters["foo"]); Assert.Equal(1, props.Parameters.Count); }
public void GetSetParameter_Collection() { var props = new AuthenticationProperties(); Assert.Null(props.GetParameter <int?>("foo")); Assert.Equal(0, props.Parameters.Count); var list = new string[] { "a", "b", "c" }; props.SetParameter <ICollection <string> >("foo", list); Assert.Equal(new string[] { "a", "b", "c" }, props.GetParameter <ICollection <string> >("foo")); Assert.Same(list, props.Parameters["foo"]); Assert.Equal(1, props.Parameters.Count); props.SetParameter <ICollection <string> >("foo", null); Assert.Null(props.GetParameter <ICollection <string> >("foo")); Assert.Null(props.Parameters["foo"]); Assert.Equal(1, props.Parameters.Count); }
public IActionResult Google(string redirectTo = null) { var properties = new AuthenticationProperties { RedirectUri = string.IsNullOrEmpty(redirectTo) ? "/home" : redirectTo }; if (Request.Cookies.TryGetValue(".Sub", out var subject) && !string.IsNullOrWhiteSpace(subject)) { properties.SetParameter("login_hint", subject); } return(Challenge(properties, "Google")); }
protected async override Task HandleChallengeAsync(AuthenticationProperties properties) { var res = await GetRequestTokenAsync(); if (res.IsSuccess && res.RequestToken != null) { properties.SetParameter("RequestToken", res.RequestToken.code); var cookieOptions = Options.CorrelationCookie.Build(Context, DateTime.Now); Response.Cookies.Append("RequestToken", res.RequestToken.code, cookieOptions); if (properties.RedirectUri != null) { Response.Cookies.Append("RedirectUri", properties.RedirectUri, cookieOptions); } await base.HandleChallengeAsync(properties); } }
public async Task OnGetAsync() { var redirectUri = HttpContext.Request.Query["returnUrl"]; if (string.IsNullOrWhiteSpace(redirectUri)) { redirectUri = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}"; } var authProperties = new AuthenticationProperties { RedirectUri = redirectUri }; authProperties.SetParameter("login_hint", "signup"); await HttpContext.ChallengeAsync("Auth0", authProperties); }
public async Task Challenge_HasOverwrittenPromptParamFromBaseAuthenticationProperties() { var settings = new TestSettings(opt => { opt.ClientId = "Test Id"; opt.Authority = TestServerBuilder.DefaultAuthority; opt.Prompt = "consent"; }); var properties = new AuthenticationProperties(); properties.SetParameter(OpenIdConnectChallengeProperties.PromptKey, "login"); var server = settings.CreateTestServer(properties); var transaction = await server.SendAsync(TestServerBuilder.TestHost + TestServerBuilder.ChallengeWithProperties); var res = transaction.Response; Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); settings.ValidateChallengeRedirect(res.Headers.Location); Assert.Contains("prompt=login", res.Headers.Location.Query); }
public async Task Challenge_HasOverwrittenMaxAgeParaFromBaseAuthenticationPropertiesm() { var settings = new TestSettings(opt => { opt.ClientId = "Test Id"; opt.Authority = TestServerBuilder.DefaultAuthority; opt.MaxAge = TimeSpan.FromSeconds(500); }); var properties = new AuthenticationProperties(); properties.SetParameter(OpenIdConnectChallengeProperties.MaxAgeKey, TimeSpan.FromSeconds(1234)); var server = settings.CreateTestServer(properties); var transaction = await server.SendAsync(TestServerBuilder.TestHost + TestServerBuilder.ChallengeWithProperties); var res = transaction.Response; Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); settings.ValidateChallengeRedirect(res.Headers.Location); Assert.Contains("max_age=1234", res.Headers.Location.Query); }
public async Task Challenge_HasOverwrittenScopeParamFromBaseAuthenticationProperties() { var settings = new TestSettings(opt => { opt.ClientId = "Test Id"; opt.Authority = TestServerBuilder.DefaultAuthority; opt.Scope.Clear(); opt.Scope.Add("foo"); opt.Scope.Add("bar"); }); var properties = new AuthenticationProperties(); properties.SetParameter(OpenIdConnectChallengeProperties.ScopeKey, new string[] { "baz", "qux" }); var server = settings.CreateTestServer(properties); var transaction = await server.SendAsync(TestServerBuilder.TestHost + TestServerBuilder.ChallengeWithProperties); var res = transaction.Response; Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); settings.ValidateChallengeRedirect(res.Headers.Location); Assert.Contains("scope=baz%20qux", res.Headers.Location.Query); }
public async Task <IActionResult> Login(UsersViewModel model) { ViewData["returnUrl"] = model.ReturnUrl; Users user = await _usersService.GetByStr(model.UserName, model.Password); if (user != null) { Dictionary <string, string> dis = new Dictionary <string, string>(); dis.Add("NameUser", "Remark"); dis.Add("Remark", "Remark"); AuthenticationProperties props = new AuthenticationProperties(dis) { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromDays(1)) }; props.SetParameter <Users>("user", user); var claims = new List <Claim>() { new Claim("NameUser", user.UserName), new Claim("Remark", user.Remark) }.ToArray(); await HttpContext.SignInAsync(user.UserName.ToString(), user.UserName, props); if (model.ReturnUrl != null) { return(Redirect(model.ReturnUrl)); } return(Redirect("/api/values")); } else { return(View()); } }
private static async Task <IHost> CreateHost(Action <MicrosoftAccountOptions> configureOptions) { var host = new HostBuilder() .ConfigureWebHost(builder => builder.UseTestServer() .Configure(app => { app.UseAuthentication(); app.Use(async(context, next) => { var req = context.Request; var res = context.Response; if (req.Path == new PathString("/challenge")) { await context.ChallengeAsync("Microsoft", new MicrosoftChallengeProperties { Prompt = "select_account", LoginHint = "username", DomainHint = "consumers", #pragma warning disable CS0618 // Type or member is obsolete ResponseMode = "query", #pragma warning restore CS0618 // Type or member is obsolete RedirectUri = "/me" }); } else if (req.Path == new PathString("/challengeWithOtherScope")) { var properties = new OAuthChallengeProperties(); properties.SetScope("baz", "qux"); await context.ChallengeAsync("Microsoft", properties); } else if (req.Path == new PathString("/challengeWithOtherScopeWithBaseAuthenticationProperties")) { var properties = new AuthenticationProperties(); properties.SetParameter(OAuthChallengeProperties.ScopeKey, new string[] { "baz", "qux" }); await context.ChallengeAsync("Microsoft", properties); } else if (req.Path == new PathString("/me")) { await res.DescribeAsync(context.User); } else if (req.Path == new PathString("/signIn")) { await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignInAsync("Microsoft", new ClaimsPrincipal())); } else if (req.Path == new PathString("/signOut")) { await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignOutAsync("Microsoft")); } else if (req.Path == new PathString("/forbid")) { await Assert.ThrowsAsync <InvalidOperationException>(() => context.ForbidAsync("Microsoft")); } else { await next(context); } }); }) .ConfigureServices(services => { services.AddAuthentication(TestExtensions.CookieAuthenticationScheme) .AddCookie(TestExtensions.CookieAuthenticationScheme, o => { }) .AddMicrosoftAccount(configureOptions); })) .Build(); await host.StartAsync(); return(host); }