protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { string header = Request.Headers[HeaderNames.Authorization]; if (string.IsNullOrEmpty(header)) { return(AuthenticateResult.Failed("Authentication failed because the bearer token " + "was missing from the 'Authorization' header.")); } // Ensure that the authorization header contains the mandatory "Bearer" scheme. // See https://tools.ietf.org/html/rfc6750#section-2.1 if (!header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { return(AuthenticateResult.Failed("Authentication failed because an invalid scheme " + "was used in the 'Authorization' header.")); } var token = header.Substring("Bearer ".Length); if (string.IsNullOrWhiteSpace(token)) { return(AuthenticateResult.Failed("Authentication failed because the bearer token " + "was missing from the 'Authorization' header.")); } // Try to unprotect the token and return an error // if the ticket can't be decrypted or validated. var ticket = Options.TicketFormat.Unprotect(token); if (ticket == null) { return(AuthenticateResult.Failed("Authentication failed because the access token was invalid.")); } // Ensure that the access token was issued // to be used with this resource server. if (!await ValidateAudienceAsync(ticket)) { return(AuthenticateResult.Failed("Authentication failed because the access token " + "was not valid for this resource server.")); } // Ensure that the authentication ticket is still valid. if (ticket.Properties.ExpiresUtc.HasValue && ticket.Properties.ExpiresUtc.Value < Options.SystemClock.UtcNow) { return(AuthenticateResult.Failed("Authentication failed because the access token was expired.")); } return(AuthenticateResult.Success(ticket)); }
protected override async Task <AuthenticateResult> HandleRemoteAuthenticateAsync() { AuthenticationProperties properties = null; var query = Request.Query; var protectedRequestToken = Request.Cookies[StateCookie]; var requestToken = DeveloperAuthOptions.StateDataFormat.Unprotect(protectedRequestToken); if (requestToken == null) { return(AuthenticateResult.Failed("Invalid state cookie.")); } properties = requestToken.Properties; // REVIEW: see which of these are really errors var cookieOptions = new CookieOptions { HttpOnly = true, Secure = Request.IsHttps }; Response.Cookies.Delete(StateCookie, cookieOptions); var accessToken = new AccessToken() { CallBackUri = requestToken.CallBackUri, CallbackConfirmed = requestToken.CallbackConfirmed, Properties = requestToken.Properties, ScreenName = Request.Form["_email"], UserId = Request.Form["_userId"] }; var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, ClaimValueTypes.String, Options.ClaimsIssuer), new Claim(ClaimTypes.Name, accessToken.ScreenName, ClaimValueTypes.String, Options.ClaimsIssuer), }, Options.ClaimsIssuer); if (Options.SaveTokensAsClaims) { identity.AddClaim(new Claim("access_token", accessToken.Token, ClaimValueTypes.String, Options.ClaimsIssuer)); } return(AuthenticateResult.Success(await CreateTicketAsync(identity, properties, accessToken))); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { var header = Request.Headers["Authorization"].ToString(); if (string.IsNullOrEmpty(header) || !header.StartsWith("Bearer ")) { return(null); } var user = header.Substring(7); var principal = PrincipalFactory.Get(user); if (principal == null) { return(AuthenticateResult.Failed("No such user")); } var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme); return(AuthenticateResult.Success(ticket)); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { var ticket = await EnsureCookieTicket(); if (ticket == null) { return(AuthenticateResult.Failed("No ticket.")); } var context = new CookieValidatePrincipalContext(Context, ticket, Options); await Options.Events.ValidatePrincipal(context); if (context.Principal == null) { return(AuthenticateResult.Failed("No principal.")); } if (context.ShouldRenew) { _shouldRenew = true; } return(AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme))); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { var ticket = await EnsureCookieTicket(); if (ticket == null) { return(AuthenticateResult.Failed("No ticket.")); } var context = new CookieValidatePrincipalContext(Context, ticket, Options); await Options.Events.ValidatePrincipal(context); if (context.Principal == null) { return(AuthenticateResult.Failed("No principal.")); } if (context.ShouldRenew) { _shouldRenew = true; } var tenantResolver = tenantResolverFactory.GetResolver(); return(AuthenticateResult.Success( new AuthenticationTicket(context.Principal, context.Properties, tenantResolver.ResolveAuthScheme(Options.AuthenticationScheme) ) )); //AuthenticationTicket ticket = null; //try //{ // ticket = await EnsureCookieTicket(); // if (ticket == null) // { // return null; // } // var context = new CookieValidatePrincipalContext(Context, ticket, Options); // this might ned change // await Options.Events.ValidatePrincipal(context); // if (context.Principal == null) // { // return null; // } // if (context.ShouldRenew) // { // _shouldRenew = true; // } // //return new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme); // var tenantResolver = tenantResolverFactory.GetResolver(); // return new AuthenticationTicket(context.Principal, context.Properties, tenantResolver.ResolveAuthScheme(Options.AuthenticationScheme)); //} //catch (Exception exception) //{ // var exceptionContext = new CookieExceptionContext(Context, Options, // CookieExceptionContext.ExceptionLocation.Authenticate, exception, ticket); // await Options.Events.Exception(exceptionContext); // if (exceptionContext.Rethrow) // { // throw; // } // return exceptionContext.Ticket; //} }
// I think this was renamed as HandleRemoteCallbackAsync // since we were not modifying this code jus commented it out to // let the base class handle it, may need to override it though needs testing //public async Task<bool> InvokeReturnPathAsync() //{ // log.LogDebug("InvokeReturnPathAsync called"); // var ticket = await HandleAuthenticateOnceAsync(); // if (ticket == null) // { // Logger.LogWarning("Invalid return state, unable to redirect."); // Response.StatusCode = 500; // return true; // } // var context = new SigningInContext(Context, ticket) // { // SignInScheme = Options.SignInScheme, // RedirectUri = ticket.Properties.RedirectUri, // }; // ticket.Properties.RedirectUri = null; // await Options.Events.SigningIn(context); // if (context.SignInScheme != null && context.Principal != null) // { // await Context.Authentication.SignInAsync(context.SignInScheme, context.Principal, context.Properties); // } // if (!context.IsRequestCompleted && context.RedirectUri != null) // { // if (context.Principal == null) // { // // add a redirect hint that sign-in failed in some way // context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "error", "access_denied"); // } // Response.Redirect(context.RedirectUri); // context.RequestCompleted(); // } // return context.IsRequestCompleted; //} protected override async Task <AuthenticateResult> HandleRemoteAuthenticateAsync() { log.LogDebug("HandleAuthenticateAsync called"); AuthenticationProperties properties = null; try { var query = Request.Query; // TODO: Is this a standard error returned by servers? var value = query["error"]; if (!string.IsNullOrEmpty(value)) { Logger.LogVerbose("Remote server returned an error: " + Request.QueryString); // TODO: Fail request rather than passing through? return(null); } var code = query["code"]; var state = query["state"]; properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(null); } // OAuth2 10.12 CSRF bool valid = await ValidateCorrelationId(properties); if (!valid) { //return new AuthenticationTicket(properties, Options.AuthenticationScheme); return(AuthenticateResult.Failed("Correlation failed.")); } if (string.IsNullOrEmpty(code)) { // Null if the remote server returns an error. //return new AuthenticationTicket(properties, Options.AuthenticationScheme); return(AuthenticateResult.Failed("Code was not found.")); } var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath)); // must be after rc1 //if (tokens.Error != null) //{ // return AuthenticateResult.Failed(tokens.Error); //} if (string.IsNullOrEmpty(tokens.AccessToken)) { Logger.LogWarning("Access token was not found"); //return new AuthenticationTicket(properties, Options.AuthenticationScheme); return(AuthenticateResult.Failed("Failed to retrieve access token.")); } var identity = new ClaimsIdentity(Options.ClaimsIssuer); if (Options.SaveTokensAsClaims) { identity.AddClaim(new Claim("access_token", tokens.AccessToken, ClaimValueTypes.String, Options.ClaimsIssuer)); if (!string.IsNullOrEmpty(tokens.RefreshToken)) { identity.AddClaim(new Claim("refresh_token", tokens.RefreshToken, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(tokens.TokenType)) { identity.AddClaim(new Claim("token_type", tokens.TokenType, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(tokens.ExpiresIn)) { identity.AddClaim(new Claim("expires_in", tokens.ExpiresIn, ClaimValueTypes.String, Options.ClaimsIssuer)); } } //return await CreateTicketAsync(identity, properties, tokens); return(AuthenticateResult.Success(await CreateTicketAsync(identity, properties, tokens))); } catch (Exception ex) { Logger.LogError("Authentication failed", ex); //return new AuthenticationTicket(properties, Options.AuthenticationScheme); return(AuthenticateResult.Failed("Authentication failed, exception logged.")); } }
protected override async Task <AuthenticateResult> HandleRemoteAuthenticateAsync() { AuthenticationProperties properties = null; var query = Request.Query; var protectedRequestToken = Request.Cookies[StateCookie]; var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken); if (requestToken == null) { return(AuthenticateResult.Failed("Invalid state cookie.")); } properties = requestToken.Properties; // REVIEW: see which of these are really errors var returnedToken = query["oauth_token"]; if (StringValues.IsNullOrEmpty(returnedToken)) { return(AuthenticateResult.Failed("Missing oauth_token")); } if (!string.Equals(returnedToken, requestToken.Token, StringComparison.Ordinal)) { return(AuthenticateResult.Failed("Unmatched token")); } var oauthVerifier = query["oauth_verifier"]; if (StringValues.IsNullOrEmpty(oauthVerifier)) { return(AuthenticateResult.Failed("Missing or blank oauth_verifier")); } var cookieOptions = new CookieOptions { HttpOnly = true, Secure = Request.IsHttps }; Response.Cookies.Delete(StateCookie, cookieOptions); var accessToken = await ObtainAccessTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, requestToken, oauthVerifier); var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, ClaimValueTypes.String, Options.ClaimsIssuer), new Claim(ClaimTypes.Name, accessToken.ScreenName, ClaimValueTypes.String, Options.ClaimsIssuer), new Claim("urn:twitter:userid", accessToken.UserId, ClaimValueTypes.String, Options.ClaimsIssuer), new Claim("urn:twitter:screenname", accessToken.ScreenName, ClaimValueTypes.String, Options.ClaimsIssuer) }, Options.ClaimsIssuer); if (Options.SaveTokensAsClaims) { identity.AddClaim(new Claim("access_token", accessToken.Token, ClaimValueTypes.String, Options.ClaimsIssuer)); } return(AuthenticateResult.Success(await CreateTicketAsync(identity, properties, accessToken))); }
#pragma warning disable 1998 protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { return(AuthenticateResult.Failed(new Exception("unknow operate"))); }
//public async Task<bool> InvokeReturnPathAsync() //{ // var model = await HandleAuthenticateOnceAsync(); // if (model == null) // { // Logger.LogWarning("Invalid return state, unable to redirect."); // Response.StatusCode = 500; // return true; // } // var context = new SigningInContext(Context, model) // { // SignInScheme = Options.SignInScheme, // RedirectUri = model.Properties.RedirectUri // }; // model.Properties.RedirectUri = null; // await Options.Events.SigningIn(context); // if (context.SignInScheme != null && context.Principal != null) // { // await Context.Authentication.SignInAsync(context.SignInScheme, context.Principal, context.Properties); // } // if (!context.IsRequestCompleted && context.RedirectUri != null) // { // if (context.Principal == null) // { // // add a redirect hint that sign-in failed in some way // context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "error", "access_denied"); // } // Response.Redirect(context.RedirectUri); // context.RequestCompleted(); // } // return context.IsRequestCompleted; //} protected override async Task <AuthenticateResult> HandleRemoteAuthenticateAsync() { AuthenticationProperties properties = null; try { var currentSite = await GetSite(); var tenantOptions = new MultiTenantTwitterOptionsResolver( Options, currentSite, multiTenantOptions); var query = Request.Query; var protectedRequestToken = Request.Cookies[tenantOptions.ResolveStateCookieName(StateCookie)]; var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken); if (requestToken == null) { Logger.LogWarning("Invalid state"); return(AuthenticateResult.Failed("Invalid state cookie.")); } properties = requestToken.Properties; var returnedToken = query["oauth_token"]; //if (StringValues.IsNullOrEmpty(returnedToken)) if (string.IsNullOrEmpty(returnedToken)) { Logger.LogWarning("Missing oauth_token"); //return new AuthenticationTicket(properties, Options.AuthenticationScheme); return(AuthenticateResult.Failed("Missing oauth_token")); } if (!string.Equals(returnedToken, requestToken.Token, StringComparison.Ordinal)) { Logger.LogWarning("Unmatched token"); //return new AuthenticationTicket(properties, Options.AuthenticationScheme); return(AuthenticateResult.Failed("Unmatched token")); } var oauthVerifier = query["oauth_verifier"]; //if (StringValues.IsNullOrEmpty(oauthVerifier)) if (string.IsNullOrEmpty(oauthVerifier)) { Logger.LogWarning("Missing or blank oauth_verifier"); //return new AuthenticationTicket(properties, Options.AuthenticationScheme); return(AuthenticateResult.Failed("Missing or blank oauth_verifier")); } var cookieOptions = new CookieOptions { HttpOnly = true, Secure = Request.IsHttps }; Response.Cookies.Delete(tenantOptions.ResolveStateCookieName(StateCookie), cookieOptions); //var accessToken = await ObtainAccessTokenAsync( // Options.ConsumerKey, // Options.ConsumerSecret, // requestToken, // oauthVerifier); var accessToken = await ObtainAccessTokenAsync( tenantOptions.ConsumerKey, tenantOptions.ConsumerSecret, requestToken, oauthVerifier); var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, ClaimValueTypes.String, Options.ClaimsIssuer), new Claim(ClaimTypes.Name, accessToken.ScreenName, ClaimValueTypes.String, Options.ClaimsIssuer), new Claim("urn:twitter:userid", accessToken.UserId, ClaimValueTypes.String, Options.ClaimsIssuer), new Claim("urn:twitter:screenname", accessToken.ScreenName, ClaimValueTypes.String, Options.ClaimsIssuer) }, Options.ClaimsIssuer); if (Options.SaveTokensAsClaims) { identity.AddClaim(new Claim("access_token", accessToken.Token, ClaimValueTypes.String, Options.ClaimsIssuer)); } //return await CreateTicketAsync(identity, properties, accessToken); return(AuthenticateResult.Success(await CreateTicketAsync(identity, properties, accessToken))); } catch (Exception ex) { Logger.LogError("Authentication failed", ex); //return new AuthenticationTicket(properties, Options.AuthenticationScheme); return(AuthenticateResult.Failed("Authentication failed, exception logged")); } }
protected override Task <AuthenticateResult> HandleAuthenticateAsync() { return(Task.FromResult(AuthenticateResult.Failed("No token found."))); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { //if accessed from a different URL - ignore if (!Request.Path.Equals(Options.CallbackPath)) { Context.Items[RedirectToEndpointKey] = true; Response.StatusCode = 302; return(AuthenticateResult.Failed("Redirecting to authentication route /windowsauthentication/ntlm")); } //check if the request has an NTLM header var authorizationHeader = Request.Headers["Authorization"]; byte[] token = null; var hasNtlm = authorizationHeader.Any(h => h.StartsWith("NTLM ")); if (!hasNtlm) { // This code runs under following conditions: // - authentication failed (in either step: IsClientResponseValid() or TryAcquireServerChallenge()) // - there's no token in the headers // // This means we've got to set the WWW-Authenticate header and return a 401 // 401 tells the browser that the request is unauthenticated and the WWW-Authenticate // header tells the browser to try again with NTLM Response.Headers.Add("WWW-Authenticate", new[] { "NTLM" }); Response.StatusCode = 401; Context.Items[RespondNoNtlmKey] = true; //We're creating a unique guid to identify the client between the //Type 2 and Type 3 handshake var requestUniqueId = Guid.NewGuid(); Response.Cookies.Append(NtlmAuthUniqueIdCookieKey, requestUniqueId.ToString()); return(AuthenticateResult.Failed("No NTLM header, returning WWW-Authenticate NTLM.")); } if (!string.IsNullOrEmpty(authorizationHeader) && hasNtlm) { var header = authorizationHeader.First(h => h.StartsWith("NTLM ")); token = Convert.FromBase64String(header.Substring(5)); } var responseUniqueId = Request.Cookies[NtlmAuthUniqueIdCookieKey]; HandshakeState state = null; //see if the response is from a known client handshake if (!string.IsNullOrWhiteSpace(responseUniqueId)) { this.Options.LoginStateCache.TryGet(responseUniqueId, out state); } if (state == null) { state = new HandshakeState(); } // First eight bytes are header containing NTLMSSP\0 signature // Next byte contains type of the message recieved. // No Token - it's the initial request. Add a authenticate header // Message Type 1 — is initial client's response to server's 401 Unauthorized error. // Message Type 2 — is the server's response to it. Contains random 8 bytes challenge. // Message Type 3 — is encrypted password hashes from client ready to server validation. if (token != null && token[8] == 1) { // Message of type 1 was received if (state.TryAcquireServerChallenge(ref token)) { // send the type 2 message var authorization = Convert.ToBase64String(token); Response.Headers.Add("WWW-Authenticate", new[] { string.Concat("NTLM ", authorization) }); Response.StatusCode = 401; Options.LoginStateCache.Add(responseUniqueId, state); Context.Items[RespondType2Key] = true; return(AuthenticateResult.Failed("Received NTLM Type 1, sending Type 2 with status 401.")); } } else if (token != null && token[8] == 3) { // message of type 3 was received, we validate it if (state.IsClientResponseValid(token)) { // Authorization successful var properties = state.AuthenticationProperties; if (Options.Filter == null || Options.Filter.Invoke(state.WindowsIdentity, Request)) { // we need to create a new identity using the sign in type that // the cookie authentication is listening for var identity = new ClaimsIdentity(Options.Cookies.ApplicationCookie.AuthenticationScheme); //Add WindowsIdentity claims to the Identity object var newClaims = new[] { new Claim(ClaimTypes.AuthenticationMethod, ActiveDirectoryOptions.DefaultAuthenticationScheme), }; identity.AddClaims(state.WindowsIdentity.Claims); // We don't need that state anymore Options.LoginStateCache.TryRemove(responseUniqueId); // create the authentication ticket var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket (principal, properties, Options.Cookies.ApplicationCookie.AuthenticationScheme); //handle the sign in method of the auth middleware await Context.Authentication.SignInAsync (Options.Cookies.ApplicationCookie.AuthenticationScheme, principal, properties); Context.Items[AuthenticatedKey] = true; //throw the succeded event await Options.Events.AuthenticationSucceeded(new Events.AuthenticationSucceededContext(Context, Options) { AuthenticationTicket = ticket //pass the ticket }); return(AuthenticateResult.Success(ticket)); } } } await Options.Events.AuthenticationFailed(new Events.AuthenticationFailedContext(Context, Options)); return(AuthenticateResult.Failed("Unauthorized")); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { try { string requestToken = null; string authorization = Request.Headers["Authorization"]; if (!string.IsNullOrEmpty(authorization)) { if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { requestToken = authorization.Substring("Bearer ".Length).Trim(); } } // Give application opportunity to find from a different location, adjust, or reject token var requestTokenContext = new OAuthRequestTokenContext(Context, requestToken); await Options.Provider.RequestToken(requestTokenContext); // If no token found, no further work possible if (string.IsNullOrEmpty(requestTokenContext.Token)) { Logger.LogWarning("access token is empty"); return(AuthenticateResult.Failed(new Exception("access token is empty"))); } // Call provider to process the token into data var tokenReceiveContext = new AuthenticationTokenReceiveContext( Context, Options.AccessTokenFormat, requestTokenContext.Token); await Options.AccessTokenProvider.ReceiveAsync(tokenReceiveContext); if (tokenReceiveContext.Ticket == null) { tokenReceiveContext.DeserializeTicket(tokenReceiveContext.Token); } AuthenticationTicket ticket = tokenReceiveContext.Ticket; if (ticket == null) { Logger.LogWarning("invalid bearer token received"); return(AuthenticateResult.Failed(new Exception("invalid bearer token received"))); } // Validate expiration time if present DateTimeOffset currentUtc = Options.SystemClock.UtcNow; if (ticket.Properties.ExpiresUtc.HasValue && ticket.Properties.ExpiresUtc.Value < currentUtc) { Logger.LogWarning("expired bearer token received"); return(AuthenticateResult.Failed(new Exception("expired bearer token received"))); } // Give application final opportunity to override results var context = new OAuthValidateIdentityContext(Context, Options, ticket); if (ticket != null && ticket.Principal != null && ticket.Principal.Identity.IsAuthenticated) { // bearer token with identity starts validated context.Validated(); } if (Options.Provider != null) { await Options.Provider.ValidateIdentity(context); } if (!context.IsValidated) { return(AuthenticateResult.Failed(context.Error)); } // resulting identity values go back to caller return(AuthenticateResult.Success(context.Ticket)); } catch (Exception ex) { Logger.LogError("Authentication failed", ex); return(AuthenticateResult.Failed(ex.Message));; } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { Uri redirectUrl; //Set the default error message when no SP Auth is attempted AuthenticateResult result = AuthenticateResult.Failed("Could not handle SharePoint authentication."); var authenticationProperties = new AuthenticationProperties() { ExpiresUtc = DateTimeOffset.UtcNow.AddDays(10), IsPersistent = false, AllowRefresh = false }; // Sets up the SharePoint configuration based on the middleware options. var spContextProvider = SharePointContextProvider.GetInstance( SharePointConfiguration.GetFromSharePointAuthenticationOptions(Options)); switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl)) { case RedirectionStatus.Ok: _redirectionStatus = RedirectionStatus.Ok; // Gets the current SharePoint context var spContext = SharePointContextProvider.Current.GetSharePointContext(Context); // Gets the SharePoint context CacheKey. The CacheKey would be assigned as issuer for new claim. // It is also used to validate identity that is authenticated. //Currently, we don't support High Trust var userCacheKey = ((SharePointAcsContext)spContext).CacheKey; // Checks if we already have an authenticated principal ClaimsPrincipal principal; if (Context.User.Identities.Any(identity => identity.IsAuthenticated && identity.HasClaim(x => x.Issuer == GetType().Assembly.GetName().Name))) { principal = Context.User; } else { //build a claims identity and principal var identity = new ClaimsIdentity(this.Options.AuthenticationScheme); // Adds claims with the SharePoint context CacheKey as issuer to the Identity object. var claims = new[] { new Claim(ClaimTypes.Authentication, userCacheKey, "SPCacheKey", GetType().Assembly.GetName().Name), }; identity.AddClaims(claims); principal = new ClaimsPrincipal(identity); // Handles the sign in method of the SP auth middleware await Context.Authentication.SignInAsync (this.Options.AuthenticationScheme, principal, authenticationProperties); //sign in the cookie middleware so it issues a cookie if (!string.IsNullOrWhiteSpace(this.Options.CookieAuthenticationScheme)) { SignInAccepted = true; await Context.Authentication.SignInAsync (this.Options.CookieAuthenticationScheme, principal, authenticationProperties); } } // Creates the authentication ticket. var ticket = new AuthenticationTicket(principal, authenticationProperties, this.Options.AuthenticationScheme); result = AuthenticateResult.Success(ticket); //Throw auth ticket success event await Options.Events.AuthenticationSucceeded( new Events.AuthenticationSucceededContext(Context, Options) { AuthenticationTicket = ticket, //pass the ticket SharePointContext = spContext //append the sp context }); //Log success LoggingExtensions.TokenValidationSucceeded(this.Logger); break; case RedirectionStatus.ShouldRedirect: _redirectionStatus = RedirectionStatus.ShouldRedirect; Response.StatusCode = 301; result = AuthenticateResult.Failed("ShouldRedirect"); // Signs out so new signin to be performed on redirect back from SharePoint await Context.Authentication.SignOutAsync(this.Options.AuthenticationScheme); // Redirect to get new context token Context.Response.Redirect(redirectUrl.AbsoluteUri); break; case RedirectionStatus.CanNotRedirect: _redirectionStatus = RedirectionStatus.CanNotRedirect; //There's a potential issue here if this is not the only auth middleware //setting the response to 401 might not be safe for the other middlewares Response.StatusCode = 401; result = AuthenticateResult.Failed("CanNotRedirect"); //Log that we cannot redirect LoggingExtensions.CannotRedirect(this.Logger); //Throw failed event await Options.Events.AuthenticationFailed(new Events.AuthenticationFailedContext(Context, Options)); break; } return(result); }
/// <summary> /// Searches the 'Authorization' header for a 'Bearer' token. If the 'Bearer' token is found, it is validated using <see cref="TokenValidationParameters"/> set in the options. /// </summary> /// <returns></returns> protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { string token = null; try { // Give application opportunity to find from a different location, adjust, or reject token var receivingTokenContext = new ReceivingTokenContext(Context, Options); // event can set the token await Options.Events.ReceivingToken(receivingTokenContext); if (receivingTokenContext.HandledResponse) { return(AuthenticateResult.Success(receivingTokenContext.AuthenticationTicket)); } if (receivingTokenContext.Skipped) { return(AuthenticateResult.Success(ticket: null)); } // If application retrieved token from somewhere else, use that. token = receivingTokenContext.Token; if (string.IsNullOrEmpty(token)) { string authorization = Request.Headers["Authorization"]; // If no authorization header found, nothing to process further if (string.IsNullOrEmpty(authorization)) { return(AuthenticateResult.Failed("No authorization header.")); } if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { token = authorization.Substring("Bearer ".Length).Trim(); } // If no token found, no further work possible if (string.IsNullOrEmpty(token)) { return(AuthenticateResult.Failed("No bearer token.")); } } // notify user token was received var receivedTokenContext = new ReceivedTokenContext(Context, Options) { Token = token, }; await Options.Events.ReceivedToken(receivedTokenContext); if (receivedTokenContext.HandledResponse) { return(AuthenticateResult.Success(receivedTokenContext.AuthenticationTicket)); } if (receivedTokenContext.Skipped) { return(AuthenticateResult.Success(ticket: null)); } if (_configuration == null && Options.ConfigurationManager != null) { _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); } var validationParameters = Options.TokenValidationParameters.Clone(); if (_configuration != null) { if (validationParameters.ValidIssuer == null && !string.IsNullOrEmpty(_configuration.Issuer)) { validationParameters.ValidIssuer = _configuration.Issuer; } else { var issuers = new[] { _configuration.Issuer }; validationParameters.ValidIssuers = (validationParameters.ValidIssuers == null ? issuers : validationParameters.ValidIssuers.Concat(issuers)); } validationParameters.IssuerSigningKeys = (validationParameters.IssuerSigningKeys == null ? _configuration.SigningKeys : validationParameters.IssuerSigningKeys.Concat(_configuration.SigningKeys)); } SecurityToken validatedToken; foreach (var validator in Options.SecurityTokenValidators) { if (validator.CanReadToken(token)) { var principal = validator.ValidateToken(token, validationParameters, out validatedToken); var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme); var validatedTokenContext = new ValidatedTokenContext(Context, Options) { AuthenticationTicket = ticket }; await Options.Events.ValidatedToken(validatedTokenContext); if (validatedTokenContext.HandledResponse) { return(AuthenticateResult.Success(validatedTokenContext.AuthenticationTicket)); } if (validatedTokenContext.Skipped) { return(AuthenticateResult.Success(ticket: null)); } return(AuthenticateResult.Success(ticket)); } } // REVIEW: this maybe return an error instead? throw new InvalidOperationException("No SecurityTokenValidator available for token: " + token ?? "null"); } catch (Exception ex) { Logger.LogError("Exception occurred while processing message", ex); // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the event. if (Options.RefreshOnIssuerKeyNotFound && ex.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) { Options.ConfigurationManager.RequestRefresh(); } var authenticationFailedContext = new AuthenticationFailedContext(Context, Options) { Exception = ex }; await Options.Events.AuthenticationFailed(authenticationFailedContext); if (authenticationFailedContext.HandledResponse) { return(AuthenticateResult.Success(authenticationFailedContext.AuthenticationTicket)); } if (authenticationFailedContext.Skipped) { return(AuthenticateResult.Success(ticket: null)); } 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.Failed("No authorization header.")); } var header = headers.Where(h => h.StartsWith(RequestHeaderPrefix)).FirstOrDefault(); if (header == null) { return(AuthenticateResult.Failed("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.Failed("Invalid basic authentication header encoding.")); } var index = decoded.IndexOf(':'); if (index == -1) { return(AuthenticateResult.Failed("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.AuthenticationTicket != null) { return(AuthenticateResult.Success(signInContext.AuthenticationTicket)); } else { return(AuthenticateResult.Failed("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.Failed("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.AuthenticationTicket)); } if (exceptionContext.Skipped) { return(AuthenticateResult.Success(null)); } throw; } }
protected override async Task <AuthenticateResult> HandleRemoteAuthenticateAsync() { AuthenticationProperties properties = null; var query = Request.Query; var error = query["error"]; if (!StringValues.IsNullOrEmpty(error)) { return(AuthenticateResult.Failed(error)); } var code = query["code"]; var state = query["state"]; properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(AuthenticateResult.Failed("The oauth state was missing or invalid.")); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties)) { return(AuthenticateResult.Failed("Correlation failed.")); } if (StringValues.IsNullOrEmpty(code)) { return(AuthenticateResult.Failed("Code was not found.")); } var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath)); if (string.IsNullOrEmpty(tokens.AccessToken)) { return(AuthenticateResult.Failed("Access token was not found.")); } var identity = new ClaimsIdentity(Options.ClaimsIssuer); if (Options.SaveTokensAsClaims) { identity.AddClaim(new Claim("access_token", tokens.AccessToken, ClaimValueTypes.String, Options.ClaimsIssuer)); if (!string.IsNullOrEmpty(tokens.RefreshToken)) { identity.AddClaim(new Claim("refresh_token", tokens.RefreshToken, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(tokens.TokenType)) { identity.AddClaim(new Claim("token_type", tokens.TokenType, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(tokens.ExpiresIn)) { identity.AddClaim(new Claim("expires_in", tokens.ExpiresIn, ClaimValueTypes.String, Options.ClaimsIssuer)); } } return(AuthenticateResult.Success(await CreateTicketAsync(identity, properties, tokens))); }