/// <summary>Gets or sets the sign in handler.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <returns>A Task.</returns> public virtual Task OnSignIn(IOwinContext context, SentinelAuthenticationOptions options) { context.Authentication.Challenge( new AuthenticationProperties() { RedirectUri = options.RedirectUri }, Constants.DefaultAuthenticationType); return(Task.FromResult <object>(null)); }
/// <summary>Gets or sets the exception handler.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <param name="ex">The exception.</param> /// <returns>A Task.</returns> public virtual Task OnException(IOwinContext context, SentinelAuthenticationOptions options, Exception ex) { var query = new QueryBuilder(); query.Add("error", ex.Message); query.Add("error_uri", context.Request.Uri.ToString()); if (context.Request.IsLocalUrl(options.Endpoints.ErrorEndpointUrl)) { context.Response.Redirect($"{options.Endpoints.ErrorEndpointUrl}{query}"); } return(Task.FromResult <object>(null)); }
/// <summary>Gets or sets the token error handler.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <param name="tokenResponse">The token response.</param> /// <returns>A Task.</returns> public virtual Task OnTokenError(IOwinContext context, SentinelAuthenticationOptions options, AccessTokenResponse tokenResponse) { var query = new QueryBuilder(); query.Add("error", "invalid_token"); query.Add("error_uri", context.Request.Uri.ToString()); if (context.Request.IsLocalUrl(options.Endpoints.ErrorEndpointUrl)) { context.Response.Redirect($"{options.Endpoints.ErrorEndpointUrl}{query}"); } return(Task.FromResult <object>(null)); }
/// <summary>Gets or sets the authorize error handler.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <param name="properties">The authentication properties.</param> /// <param name="errorType">Type of the error.</param> /// <returns>A Task.</returns> public virtual Task OnStateError(IOwinContext context, SentinelAuthenticationOptions options, AuthenticationProperties properties, string errorType) { var query = new QueryBuilder(); query.Add("error", errorType); query.Add("error_uri", context.Request.Uri.ToString()); if (context.Request.IsLocalUrl(options.Endpoints.ErrorEndpointUrl)) { context.Response.Redirect($"{options.Endpoints.ErrorEndpointUrl}{query}"); } return(Task.FromResult <object>(null)); }
/// <summary>Gets or sets the authorize error handler.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <param name="errorTitle">The error title.</param> /// <param name="errorDescription">The error description.</param> /// <param name="errorUri">The error URI.</param> /// <returns>A Task.</returns> public virtual Task OnAuthorizeError(IOwinContext context, SentinelAuthenticationOptions options, string errorTitle, string errorDescription, string errorUri) { var query = new QueryBuilder(); query.Add("error", errorTitle); query.Add("error_description", errorDescription); query.Add("error_uri", errorUri); if (context.Request.IsLocalUrl(options.Endpoints.ErrorEndpointUrl)) { context.Response.Redirect($"{options.Endpoints.ErrorEndpointUrl}{query}"); } return(Task.FromResult <object>(null)); }
/// <summary>Handles the error endpoint requests.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <returns>A Task.</returns> public virtual async Task OnError(IOwinContext context, SentinelAuthenticationOptions options) { var error = context.Request.Query["error"]; var errorDescription = context.Request.Query["error_description"]; var errorUri = context.Request.Query["error_uri"]; var response = new ErrorResponse(error) { ErrorDescription = errorDescription, ErrorUri = errorUri }; context.Response.ContentType = "application/json"; await context.Response.WriteAsync(JsonConvert.SerializeObject(response)); }
/// <summary>Refreshes the token.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <returns>A Task.</returns> public virtual async Task OnRefresh(IOwinContext context, SentinelAuthenticationOptions options) { var user = new SentinelPrincipal(context.Authentication.User); // Always return json from this endpoint context.Response.ContentType = "application/json"; // Dont refresh if user is authenticated and more than 1 minute remains of its validness if (user.Identity.IsAuthenticated && user.ValidTo.Subtract(DateTimeOffset.UtcNow) > TimeSpan.FromMinutes(1)) { return; } var refreshCookie = context.Request.Cookies.FirstOrDefault(x => x.Key == $"{options.CookieConfiguration.Name}_RT"); if (refreshCookie.Value != null) { var refreshTokenResponse = await options.TicketHandler.RefreshTokenAsync(context, options, refreshCookie.Value, options.RedirectUri); if (refreshTokenResponse != null) { // Sign in as sentinel identity var props = new AuthenticationProperties() { RedirectUri = context.Request.Uri.ToString() }; var ticket = await options.TicketHandler.SignInAsync(context, options, refreshTokenResponse, props); await options.Events.OnTokenRefreshed(context, ticket, options); await context.Response.WriteAsync(JsonConvert.SerializeObject(refreshTokenResponse)); return; } 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 context.Response.Cookies.Delete($"{options.CookieConfiguration.Name}_RT", new CookieOptions() { Domain = context.Request.Uri.Host, Secure = context.Request.IsSecure }); } context.Response.StatusCode = (int)HttpStatusCode.BadRequest; await context.Response.WriteAsync(JsonConvert.SerializeObject(new ErrorResponse("invalid_refresh_token"))); }
/// <summary>Executes the authorize callback action.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <returns>A Task.</returns> public virtual async Task OnAuthorizeCallback(IOwinContext context, SentinelAuthenticationOptions options) { if (context.Authentication.User != null && context.Authentication.User.Identity.IsAuthenticated) { var sentinelIdentity = context.Authentication.User.Identities.FirstOrDefault(x => x.AuthenticationType == Constants.DefaultAuthenticationType); if (sentinelIdentity == null) { return; } var props = options.StateDataFormat.Unprotect(context.Request.Query["state"]); if (context.Authentication.AuthenticationResponseGrant != null) { props = context.Authentication.AuthenticationResponseGrant.Properties; } var cookieIdentity = new ClaimsIdentity(sentinelIdentity.Claims, DefaultAuthenticationTypes.ApplicationCookie); // Persist cookie if it has an expire date if (props.ExpiresUtc != null) { props.IsPersistent = true; } context.Authentication.SignIn(props, cookieIdentity); // Redirect to returnurl if valid if (context.Request.IsLocalUrl(props.RedirectUri)) { context.Response.Redirect(props.RedirectUri); } else { context.Response.Redirect("/"); } } }
/// <summary>Gets or sets the sign out handler.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="options">The authentication options.</param> /// <returns>A Task.</returns> public virtual Task OnSignOut(IOwinContext context, SentinelAuthenticationOptions options) { var props = new AuthenticationProperties() { RedirectUri = context.Request.Query["ReturnUrl"] }; context.Authentication.SignOut(props, Constants.DefaultAuthenticationType); context.Authentication.SignOut(props, DefaultAuthenticationTypes.ApplicationCookie); // Redirect to returnurl if specified, otherwise base url if (context.Request.IsLocalUrl(props.RedirectUri)) { context.Response.Redirect(props.RedirectUri); } else { context.Response.Redirect("/"); } return(Task.FromResult <object>(null)); }
/// <summary>Executes the token refreshed action.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="ticket">The ticket.</param> /// <param name="options">The authentication options.</param> /// <returns>A Task.</returns> public virtual async Task OnTokenRefreshed(IOwinContext context, AuthenticationTicket ticket, SentinelAuthenticationOptions options) { // Login with cookie identity at once var cookieIdentity = new ClaimsIdentity(ticket.Identity.Claims, DefaultAuthenticationTypes.ApplicationCookie); // Persist cookie if it has an expire date if (ticket.Properties.ExpiresUtc != null) { ticket.Properties.IsPersistent = true; } context.Authentication.SignIn(ticket.Properties, cookieIdentity); }
/// <summary>Gets or sets the authenticated handler.</summary> /// <param name="context">The current OWIN context.</param> /// <param name="identity">The identity.</param> /// <param name="properties">The authentication properties.</param> /// <param name="options">The authentication options.</param> /// <returns>A Task.</returns> public virtual Task OnAuthenticated(IOwinContext context, ClaimsIdentity identity, AuthenticationProperties properties, SentinelAuthenticationOptions options) { if (properties.Dictionary.ContainsKey("access_token") && !identity.HasClaim(x => x.Type == "access_token")) { identity.AddClaim(new Claim("access_token", properties.Dictionary["access_token"])); } if (properties.Dictionary.ContainsKey("refresh_token") && !identity.HasClaim(x => x.Type == "refresh_token")) { identity.AddClaim(new Claim("refresh_token", properties.Dictionary["refresh_token"])); } return(Task.FromResult <object>(null)); }
public virtual async Task <AccessTokenResponse> RefreshTokenAsync(IOwinContext context, SentinelAuthenticationOptions options, string refreshToken, string redirectUri) { // Build up the body for the token request var tokenRequestParameters = new Dictionary <string, string> { { "grant_type", "refresh_token" }, { "refresh_token", refreshToken }, { "redirect_uri", redirectUri } }; var requestContent = new FormUrlEncodedContent(tokenRequestParameters); var requestMessage = new HttpRequestMessage(HttpMethod.Post, options.Endpoints.TokenEndpointUrl); requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); requestMessage.Headers.Authorization = new BasicAuthenticationHeaderValue(options.ClientId, options.ClientSecret); requestMessage.Content = requestContent; var response = await options.Backchannel.SendAsync(requestMessage); if (response.IsSuccessStatusCode) { return(JsonConvert.DeserializeObject <AccessTokenResponse>(await response.Content.ReadAsStringAsync())); } return(null); }
public virtual async Task <AuthenticationTicket> SignInAsync(IOwinContext context, SentinelAuthenticationOptions options, AccessTokenResponse tokenResponse, AuthenticationProperties properties) { // Get user identity var identity = new ClaimsIdentity(); if (!string.IsNullOrEmpty(tokenResponse.IdToken)) { var jwt = new JsonWebToken(tokenResponse.IdToken); identity = jwt.ToIdentity(Constants.DefaultAuthenticationType).ToClaimsIdentity(); } else { // TODO: Get user by making a request to the userinfo endpoint } // Add tokens to ticket properties.Dictionary.Add("access_token", tokenResponse.AccessToken); if (!string.IsNullOrEmpty(tokenResponse.RefreshToken)) { properties.Dictionary.Add("refresh_token", tokenResponse.RefreshToken); } if (!string.IsNullOrEmpty(tokenResponse.IdToken)) { properties.Dictionary.Add("id_token", tokenResponse.IdToken); } if (!string.IsNullOrEmpty(tokenResponse.TokenType)) { properties.Dictionary.Add("token_type", tokenResponse.TokenType); } if (tokenResponse.ExpiresIn > 0) { var expiresAt = options.SystemClock.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn); properties.Dictionary.Add("expires_in", tokenResponse.ExpiresIn.ToString(CultureInfo.InvariantCulture)); properties.ExpiresUtc = expiresAt; } await options.Events.OnAuthenticated(context, identity, properties, options); // Add authentication response grant so it is accessible in the callback context.Authentication.AuthenticationResponseGrant = new AuthenticationResponseGrant(identity, properties); return(new AuthenticationTicket(identity, properties)); }