public ActionResult SignOut() { if (!Request.IsAuthenticated) { return(RedirectToAction("SignedOut")); } else { // [NOTE] Remove the token cache for this user and send an OpenID Connect sign-out request. TokenCacheFactory.DeleteTokenCacheForPrincipal(this.User); HttpContext.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType); return(new EmptyResult()); // The SignOut will take care of the response. } }
public async Task <IActionResult> SignOut() { if (!User.Identity.IsAuthenticated) { return(RedirectToAction("SignedOut")); } else { // [NOTE] Remove the token cache for this user and send an OpenID Connect sign-out request. TokenCacheFactory.DeleteTokenCacheForPrincipal(this.User); await HttpContext.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.Authentication.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme); return(new EmptyResult()); // The SignOut will take care of the response. } }
public async Task SetReminder(IBotContext context, int contractHours, ConversationReference conversation) { string username = context.Activity.From.Name; if (_store.GetReminder(username) != null) { await context.PostAsync("I tried to set-up a reminder for you, but it was already there!"); } else { TokenCache tokenCache = TokenCacheFactory.GetTokenCache(); HoursReminderModel model = new HoursReminderModel(username, conversation, contractHours, tokenCache); _store.AddReminder(model); await context.PostAsync("Sure thing! I will remind you about booking your hours at the end of every week."); } }
//public HoursReminderService(IHoursReminderStore store, ConversationReference conversation) //{ // SetField.NotNull(out this._store, nameof(_store), store); // SetField.NotNull(out this._conversation, nameof(_conversation), conversation); //} //public HoursReminderService(IHoursReminderStore store, ConversationReference conversation) //{ // SetField.NotNull(out this._store, nameof(store), store); // SetField.NotNull(out this._conversation, nameof(conversation), conversation); //} public async Task ProcessReminders(CancellationToken token) { IHoursReminderStore store = new HoursReminderStore(); IEnumerable <HoursReminderModel> reminders = store.GetReminders(); // process all stored reminders... fetch the number of hours missing for that user and // then send the user a message as a reminder foreach (HoursReminderModel reminder in reminders) { try { TokenCacheFactory.SetTokenCache(reminder.TokenCache); var authToken = await ExactOnlineHelper.GetToken(); ConversationReference conversation = reminder.GetConversationReference(); double?bookedHours = await GetBookedHours(authToken); int contractHours = reminder.ContractHours ?? 40; // TODO: need to get the contracted hours from somewhere if (bookedHours == null) { await SendReminder(conversation, "Hey! I tried to look at your hours but I was unable to. Could you be so kind to do it yourself? Thanks!", token); } else if (bookedHours == 0) { await SendReminder(conversation, $"Hey! I noticed you didn't book any hours yet for this week. You can ask me to book your hours, or do so yourself in Exact.", token); } else if (bookedHours < contractHours) { await SendReminder(conversation, $"Hey! I noticed you've booked {bookedHours} hours this week, I was expecting {contractHours}. Can you please book the rest?", token); } } catch (Exception ex) { Trace.TraceError($"Something went wrong processing the reminders: {ex}."); } } }
public void ConfigureAuth(IAppBuilder app) { var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext); var postLogoutRedirectUri = new Uri(new Uri(SiteConfiguration.TodoListWebAppRootUrl), urlHelper.Action("SignedOut", "Account")).ToString(); // [NOTE] Use cookies to keep the user session active after having signed in. // By default, the cookie lifetime will be the same as the token lifetime. app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); // [SCENARIO] OpenID Connect app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { ClientId = SiteConfiguration.TodoListWebAppClientId, Authority = StsConfiguration.Authority, PostLogoutRedirectUri = postLogoutRedirectUri, RedirectUri = SiteConfiguration.TodoListWebAppRootUrl, TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters { NameClaimType = StsConfiguration.NameClaimType, RoleClaimType = StsConfiguration.RoleClaimType }, Notifications = new OpenIdConnectAuthenticationNotifications() { AuthorizationCodeReceived = async(context) => { // [SCENARIO] OAuth 2.0 Authorization Code Grant, Confidential Client // If there is an authorization code in the OpenID Connect response, redeem it for // an access token and refresh token, and store those away in the cache. // Note that typically this is a "Multiple Resource Refresh Token" which means the // refresh token can be used not only against the requested "resource" but also against // any other resource defined in the same directory tenant the user has access to. var credential = new ClientCredential(SiteConfiguration.TodoListWebAppClientId, SiteConfiguration.TodoListWebAppClientSecret); var userId = context.AuthenticationTicket.Identity.GetUniqueIdentifier(); var authContext = new AuthenticationContext(StsConfiguration.Authority, StsConfiguration.CanValidateAuthority, TokenCacheFactory.GetTokenCache(userId)); var result = await authContext.AcquireTokenByAuthorizationCodeAsync(context.Code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, SiteConfiguration.TodoListWebApiResourceId); // No need to do anything with the result at this time, it is stored in the cache // for later use. }, AuthenticationFailed = context => { context.HandleResponse(); context.Response.Redirect(urlHelper.Action("Error", "Home", new { message = context.Exception.Message })); return(Task.FromResult(0)); } } }); }
private static async Task <HttpClient> GetTodoListClient(IPrincipal user) { // [SCENARIO] OAuth 2.0 Authorization Code Grant, Confidential Client // Get a token to authenticate against the Web API. var authContext = new AuthenticationContext(StsConfiguration.Authority, StsConfiguration.CanValidateAuthority, TokenCacheFactory.GetTokenCacheForPrincipal(user)); var credential = new ClientCredential(SiteConfiguration.TodoListWebFormsClientId, SiteConfiguration.TodoListWebFormsClientSecret); var userIdentifier = new UserIdentifier(user.GetUniqueIdentifier(), UserIdentifierType.UniqueId); // We can acquire the token silently here because we have redeemed the OpenID Connect authorization code at signin // for an access token and stored it in the token cache. var result = await authContext.AcquireTokenSilentAsync(SiteConfiguration.TodoListWebApiResourceId, credential, userIdentifier); var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); return(client); }
internal static async Task <HttpClient> GetTaxonomyClient(IPrincipal user) { // [SCENARIO] OAuth 2.0 On-Behalf-Of Grant // Get an On-Behalf-Of token to authenticate against the Taxonomy Web API. var authContext = new AuthenticationContext(StsConfiguration.Authority, StsConfiguration.CanValidateAuthority, TokenCacheFactory.GetTokenCacheForPrincipal(user)); var credential = new ClientCredential(SiteConfiguration.TodoListWebApiClientId, SiteConfiguration.TodoListWebApiClientSecret); var userIdentity = (ClaimsIdentity)user.Identity; var bootstrapContext = userIdentity.BootstrapContext as System.IdentityModel.Tokens.BootstrapContext; var userAssertion = new UserAssertion(bootstrapContext.Token); var result = await authContext.AcquireTokenAsync(SiteConfiguration.TaxonomyWebApiResourceId, credential, userAssertion); var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); return(client); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); // [NOTE] Use cookies to keep the user session active after having signed in. // By default, the cookie lifetime will be the same as the token lifetime. app.UseCookieAuthentication(new CookieAuthenticationOptions { AutomaticAuthenticate = true }); // [SCENARIO] OpenID Connect app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions { AutomaticChallenge = true, Authority = StsConfiguration.Authority, ClientId = this.SiteConfiguration.TodoListWebCoreClientId, ClientSecret = this.SiteConfiguration.TodoListWebCoreClientSecret, ResponseType = OpenIdConnectResponseType.CodeIdToken, // We want to retrieve an ID token as well as an authorization code (hybrid flow). SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme, SaveTokens = true, // Persists the tokens in the cookie, so they can be retrieved later with e.g. "this.HttpContext.Authentication.GetTokenAsync(...)". TokenValidationParameters = new TokenValidationParameters { NameClaimType = StsConfiguration.NameClaimType, RoleClaimType = StsConfiguration.RoleClaimType }, Events = new OpenIdConnectEvents { OnAuthorizationCodeReceived = async(context) => { // [SCENARIO] OAuth 2.0 Authorization Code Grant, Confidential Client // If there is an authorization code in the OpenID Connect response, redeem it for // an access token and refresh token, and store those away in the cache. // Note that typically this is a "Multiple Resource Refresh Token" which means the // refresh token can be used not only against the requested "resource" but also against // any other resource defined in the same directory tenant the user has access to. var credential = new ClientCredential(this.SiteConfiguration.TodoListWebCoreClientId, this.SiteConfiguration.TodoListWebCoreClientSecret); var userId = context.Ticket.Principal.GetUniqueIdentifier(); var authContext = new AuthenticationContext(StsConfiguration.Authority, StsConfiguration.CanValidateAuthority, TokenCacheFactory.GetTokenCache(userId)); var redirectUri = new Uri(string.Format("{0}://{1}{2}{3}", context.Request.Scheme, context.Request.Host.ToUriComponent(), context.Request.PathBase.ToUriComponent(), context.Request.Path.ToUriComponent())); var result = await authContext.AcquireTokenByAuthorizationCodeAsync(context.ProtocolMessage.Code, redirectUri, credential, this.SiteConfiguration.TodoListWebApiResourceId); context.HandleCodeRedemption(result.AccessToken, result.IdToken); // No need to do anything with the result at this time, it is stored in the cache // for later use. }, OnRemoteFailure = (context) => { // Handle sign-in errors differently than generic errors. context.HandleResponse(); context.Response.Redirect("/Home/Error?message=" + WebUtility.UrlEncode(context.Failure.Message)); return(Task.FromResult(0)); } } }); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }