private ClaimsPrincipal SignInUsingSecret(BasicSignInContext context) { if (_options.Secret != context.Password) { return null; } var claims = new[] { new Claim(ClaimTypes.Name, context.Username), new Claim(Claims.RUser, "") }; var identity = new ClaimsIdentity(claims, context.Options.AuthenticationScheme); return new ClaimsPrincipal(identity); }
public async Task SignInAsync(BasicSignInContext context) { ClaimsPrincipal principal; if (context.IsSignInRequired()) { principal = (_options.Secret != null) ? SignInUsingSecret(context) : await SignInUsingLogonAsync(context); } else { var claims = new[] { new Claim(ClaimTypes.Anonymous, "") }; var claimsIdentity = new ClaimsIdentity(claims, context.Options.AuthenticationScheme); principal = new ClaimsPrincipal(claimsIdentity); } if (principal != null) { context.Ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), context.Options.AuthenticationScheme); } context.HandleResponse(); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { var events = Events as BasicEvents; try { // .NET Core as of 2.0 does not support HTTP auth on sockets // This is alternative solution to anonymous access in SessionController.GetPipe() // but it only works for local connections (which may be OK for VSC but it won't work // in VSC with remote or Docker containers. //if (Uri.TryCreate(CurrentUri, UriKind.Absolute, out var uri)) { // if (uri.IsLoopback && !Request.IsHttps) { // var claims = new[] { // new Claim(ClaimTypes.Name, "RTVS"), // new Claim(Claims.RUser, string.Empty), // }; // var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, BasicDefaults.AuthenticationScheme)); // var t = new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name); // return AuthenticateResult.Success(t); // } //} // retrieve authorization header string authorization = Request.Headers[HeaderNames.Authorization]; if (string.IsNullOrEmpty(authorization)) { return(AuthenticateResult.NoResult()); } if (!authorization.StartsWith(RequestHeaderPrefix, StringComparison.OrdinalIgnoreCase)) { return(AuthenticateResult.NoResult()); } // retrieve credentials from header var encodedCredentials = authorization.Substring(RequestHeaderPrefix.Length); var decodedCredentials = default(string); try { decodedCredentials = Encoding.UTF8.GetString(Convert.FromBase64String(encodedCredentials)); } catch (Exception) { return(AuthenticateResult.Fail("Invalid basic authentication header encoding.")); } var index = decodedCredentials.IndexOf(':'); if (index == -1) { return(AuthenticateResult.Fail("Invalid basic authentication header format.")); } var username = decodedCredentials.Substring(0, index); var password = decodedCredentials.Substring(index + 1); var signInContext = new BasicSignInContext(Context, Scheme, Options) { Username = username, Password = password, }; await events.SignIn(signInContext); if (signInContext.Principal == null) { return(AuthenticateResult.Fail("Invalid basic authentication credentials.")); } var ticket = new AuthenticationTicket(signInContext.Principal, new AuthenticationProperties(), Scheme.Name); return(AuthenticateResult.Success(ticket)); } catch (Exception ex) { var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options) { Exception = ex, }; await events.AuthenticationFailed(authenticationFailedContext); if (authenticationFailedContext.Result != null) { return(authenticationFailedContext.Result); } throw; } }
/// <summary> /// Implements the interface method by invoking the related delegate method /// </summary> /// <param name="context"></param> public virtual Task SignIn(BasicSignInContext context) => OnSignIn(context);
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { try { // retrieve authorization header string authorization = Request.Headers[HeaderNames.Authorization]; if (string.IsNullOrEmpty(authorization)) { return(AuthenticateResult.NoResult()); } if (!authorization.StartsWith(RequestHeaderPrefix, StringComparison.OrdinalIgnoreCase)) { return(AuthenticateResult.NoResult()); } // retrieve credentials from header var encodedCredentials = authorization.Substring(RequestHeaderPrefix.Length); var decodedCredentials = default(string); try { decodedCredentials = Encoding.UTF8.GetString(Convert.FromBase64String(encodedCredentials)); } catch (Exception) { return(AuthenticateResult.Fail("Invalid basic authentication header encoding.")); } var index = decodedCredentials.IndexOf(':'); if (index == -1) { return(AuthenticateResult.Fail("Invalid basic authentication header format.")); } var username = decodedCredentials.Substring(0, index); var password = decodedCredentials.Substring(index + 1); // invoke sign in event var signInContext = new BasicSignInContext(Context, Scheme, Options) { Username = username, Password = password, }; await Events.SignIn(signInContext); if (signInContext.Result != null) { return(signInContext.Result); } // allow sign in event to modify received credentials username = signInContext.Username; password = signInContext.Password; // verify credentials against options BasicCredential credentials = null; for (var i = 0; i < Options.Credentials.Length; i++) { var currentCredentials = Options.Credentials[i]; if (currentCredentials.Username == username && currentCredentials.Password == password) { credentials = currentCredentials; break; } } if (credentials == null) { return(AuthenticateResult.Fail("Invalid basic authentication credentials.")); } var claims = new Claim[credentials.Claims.Length + 1]; claims[0] = new Claim(ClaimsIdentity.DefaultNameClaimType, credentials.Username); for (var i = 0; i < credentials.Claims.Length; i++) { var currentClaim = credentials.Claims[i]; claims[i + 1] = new Claim(currentClaim.Type, currentClaim.Value); } var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, Scheme.Name)); var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name); return(AuthenticateResult.Success(ticket)); } catch (Exception ex) { var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options) { Exception = ex, }; await Events.AuthenticationFailed(authenticationFailedContext); if (authenticationFailedContext.Result != null) { return(authenticationFailedContext.Result); } throw; } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { try { var feat = Context.Features.OfType <HttpRequestFeature>(); var headers = Request.Headers[RequestHeader]; if (headers.Count <= 0) { return(AuthenticateResult.Fail("No authorization header.")); } var header = headers.Where(h => h.StartsWith(RequestHeaderPrefix, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); if (header == null) { return(AuthenticateResult.Fail("Not basic authentication header.")); } var encoded = header.Substring(RequestHeaderPrefix.Length); var decoded = default(string); try { decoded = Encoding.UTF8.GetString(Convert.FromBase64String(encoded)); } catch (Exception) { return(AuthenticateResult.Fail("Invalid basic authentication header encoding.")); } var index = decoded.IndexOf(':'); if (index == -1) { return(AuthenticateResult.Fail("Invalid basic authentication header format.")); } var username = decoded.Substring(0, index); var password = decoded.Substring(index + 1); var signInContext = new BasicSignInContext(Context, Options, username, password); await Options.Events.SignIn(signInContext); if (signInContext.HandledResponse) { if (signInContext.Ticket != null) { return(AuthenticateResult.Success(signInContext.Ticket)); } else { return(AuthenticateResult.Fail("Invalid basic authentication credentials.")); } } if (signInContext.Skipped) { return(AuthenticateResult.Success(null)); } var credentials = Options.Credentials.Where(c => c.Username == username && c.Password == password).FirstOrDefault(); if (credentials == null) { return(AuthenticateResult.Fail("Invalid basic authentication credentials.")); } var claims = credentials.Claims.Select(c => new Claim(c.Type, c.Value)).ToList(); if (!claims.Any(c => c.Type == ClaimTypes.Name)) { claims.Add(new Claim(ClaimTypes.Name, username)); } var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, Options.AuthenticationScheme)); var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme); return(AuthenticateResult.Success(ticket)); } catch (Exception ex) { var exceptionContext = new BasicExceptionContext(Context, Options, ex); await Options.Events.Exception(exceptionContext); if (exceptionContext.HandledResponse) { return(AuthenticateResult.Success(exceptionContext.Ticket)); } if (exceptionContext.Skipped) { return(AuthenticateResult.Success(null)); } throw; } }
private async Task<ClaimsPrincipal> SignInUsingLogonAsync(BasicSignInContext context) { var user = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH + 1); var domain = new StringBuilder(NativeMethods.CREDUI_MAX_PASSWORD_LENGTH + 1); uint error = NativeMethods.CredUIParseUserName(context.Username, user, user.Capacity, domain, domain.Capacity); if (error != 0) { _logger.LogError(Resources.Error_UserNameParse, context.Username, error.ToString("X")); return null; } IntPtr token; WindowsIdentity winIdentity = null; string profilePath = string.Empty; _logger.LogTrace(Resources.Trace_LogOnUserBegin, context.Username); if (NativeMethods.LogonUser(user.ToString(), domain.ToString(), context.Password, (int)LogonType.LOGON32_LOGON_NETWORK, (int)LogonProvider.LOGON32_PROVIDER_DEFAULT, out token)) { _logger.LogTrace(Resources.Trace_LogOnSuccess, context.Username); winIdentity = new WindowsIdentity(token); StringBuilder profileDir = new StringBuilder(NativeMethods.MAX_PATH * 2); uint size = (uint)profileDir.Capacity; if (NativeMethods.GetUserProfileDirectory(token, profileDir, ref size)) { profilePath = profileDir.ToString(); _logger.LogTrace(Resources.Trace_UserProfileDirectory, context.Username, profilePath); } else { #if DEBUG CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMinutes(10)); #else CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); #endif _logger.LogTrace(Resources.Trace_UserProfileCreation, context.Username); var result = await _userProfileManager.CreateProfileAsync(new RUserProfileServiceRequest(user.ToString(), domain.ToString(), context.Password.ToSecureString()), cts.Token); if (result.IsInvalidResponse()) { _logger.LogError(Resources.Error_ProfileCreationFailedInvalidResponse, context.Username, Resources.Info_UserProfileServiceName); return null; } error = result.Error; // 0x800700b7 - Profile already exists. if (error != 0 && error != 0x800700b7) { _logger.LogError(Resources.Error_ProfileCreationFailed, context.Username, error.ToString("X")); return null; } else if (error == 0x800700b7 || result.ProfileExists) { _logger.LogInformation(Resources.Info_ProfileAlreadyExists, context.Username); } else { _logger.LogInformation(Resources.Info_ProfileCreated, context.Username); } if (!string.IsNullOrEmpty(result.ProfilePath)) { profilePath = result.ProfilePath; _logger.LogTrace(Resources.Trace_UserProfileDirectory, context.Username, profilePath); } else { _logger.LogError(Resources.Error_GetUserProfileDirectory, context.Username, Marshal.GetLastWin32Error().ToString("X")); } } } else { _logger.LogError(Resources.Error_LogOnFailed, context.Username, Marshal.GetLastWin32Error().ToString("X")); return null; } var principal = new WindowsPrincipal(winIdentity); if (principal.IsInRole(_options.AllowedGroup)) { var claims = new[] { //new Claim(ClaimTypes.Name, context.Username), new Claim(Claims.RUser, ""), // TODO: figure out how to avoid keeping raw credentials around. new Claim(Claims.Password, context.Password), new Claim(Claims.RUserProfileDir, profilePath) }; var claimsIdentity = new ClaimsIdentity(claims, context.Options.AuthenticationScheme); principal.AddIdentities(new[] { claimsIdentity }); } return principal; }