コード例 #1
0
    public async Task<ActionResult> Authorize()
    {
      string authCode = Request.Params["code"];
      if (string.IsNullOrEmpty(authCode))
      {
        string error = Request.Params["error"];
        string error_description = Request.Params["error_description"];

        TempData["error_message"] = string.Format("Error: {0} - {1}", error, error_description);
        return RedirectToAction("Error");
      }

      AuthenticationContext authContext = new AuthenticationContext(authority);

      ClientCredential credential = new ClientCredential(appId, appSecret);
      AuthenticationResult authResult = null;
      Uri redirectUri = new Uri(Url.Action("Authorize", "Home", null, Request.Url.Scheme));

      try
      {
        authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(authCode, redirectUri, credential, scopes);
      }
      catch (AdalException ex)
      {
        TempData["error_message"] = ex.Message;
        return RedirectToAction("Error");
      }

      return Redirect("/");
    }
コード例 #2
0
        // Note the function signature is changed!
        public async Task<ActionResult> Authorize()
        {
            // Get the 'code' parameter from the Azure redirect
            string authCode = Request.Params["code"];

            string authority = "https://login.microsoftonline.com/common";
            string clientId = System.Configuration.ConfigurationManager.AppSettings["ida:ClientID"]; ;
            string clientSecret = System.Configuration.ConfigurationManager.AppSettings["ida:ClientSecret"]; ;
            AuthenticationContext authContext = new AuthenticationContext(authority);
            
            // The same url we specified in the auth code request
            Uri redirectUri = new Uri(Url.Action("Authorize", "Home", null, Request.Url.Scheme));

            // Use client ID and secret to establish app identity
            ClientCredential credential = new ClientCredential(clientId, clientSecret);

            try
            {
                // Get the token
                var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                    authCode, redirectUri, credential, scopes);

                // Save the token in the session
                Session["access_token"] = authResult.Token;
                
                // Try to get user info
                Session["user_email"] = GetUserEmail(authContext, clientId);

                return Redirect(Url.Action("Inbox", "Home", null, Request.Url.Scheme));
            }
            catch (AdalException ex)
            {
                return Content(string.Format("ERROR retrieving token: {0}", ex.Message));
            }
        }
コード例 #3
0
        public async Task<IActionResult> Authorize()
        {
            // Get the 'code' parameter from the Azure redirect
            string authCode = Request.Query["code"];

            string authority = "https://login.microsoftonline.com/common";
            AuthenticationContext authContext = new AuthenticationContext(authority);

            // The same url we specified in the auth code request
            Uri redirectUri = new Uri(Url.Action("Authorize", "Outlook", null, "http"));

            // Use client ID and secret to establish app identity
            ClientCredential credential = new ClientCredential(ClientId, ClientSecret);

            try
            {
                // Get the token
                var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                    authCode, redirectUri, credential, scopes);

                // Save the token in the session
                Context.Session.SetString("access_token", authResult.Token);

                // Try to get user info
                Context.Session.SetString("user_email", GetUserEmail(authContext, ClientId));

                return Content("Access Token: " + authResult.Token);
            }
            catch (AdalException ex)
            {
                return Content($"ERROR retrieving token: {ex.Message}");
            }
        }
コード例 #4
0
        public void ConfigureAuth(IAppBuilder app)
        {
            //var cookieType = CookieAuthenticationDefaults.AuthenticationType; //"Cookies";
            //var cookieType = DefaultAuthenticationTypes.ExternalCookie;
            //app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            //var cookieType = DefaultAuthenticationTypes.ApplicationCookie;
            //app.UseCookieAuthentication(new CookieAuthenticationOptions {
            //  AuthenticationType = cookieType,
            //  CookieName = "MVCcookieOIDC"
            //});

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions {
                Caption = "Azure AD ***custom***",
                SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,

                ClientId              = clientId,
                Authority             = Authority,
                PostLogoutRedirectUri = postLogoutRedirectUri,

                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                    AuthorizationCodeReceived = (context) => {
                        var code = context.Code;
                        ClientCredential credential       = new ClientCredential(clientId, appKey);
                        string signedInUserID             = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                        AuthenticationContext authContext = new AuthenticationContext(Authority, new ADALTokenCache(signedInUserID));
                        return(authContext.AcquireTokenByAuthorizationCodeAsync(
                                   code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId));

                        //return Task.Run(() => { });
                    },

                    AuthenticationFailed = (context) => {
                        return(Task.Run(() => { }));
                    },
                    MessageReceived = (context) => {
                        return(Task.Run(() => { }));
                    },
                    RedirectToIdentityProvider = (context) => {
                        return(Task.Run(() => { }));
                    },
                    SecurityTokenReceived = (context) => {
                        return(Task.Run(() => { }));
                    },
                    SecurityTokenValidated = (context) => {
                        return(Task.Run(() => { }));
                    },
                }

                //public Func<AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>, Task> AuthenticationFailed { get; set; }
                //public Func<AuthorizationCodeReceivedNotification, Task> AuthorizationCodeReceived { get; set; }
                //public Func<MessageReceivedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>, Task> MessageReceived { get; set; }
                //public Func<RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>, Task> RedirectToIdentityProvider { get; set; }
                //public Func<SecurityTokenReceivedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>, Task> SecurityTokenReceived { get; set; }
                //public Func<SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>, Task> SecurityTokenValidated { get; set; }
            });
        }
        public void ConfigureAuth(IAppBuilder app)
        {
            string clientId        = ConfigurationManager.AppSettings["ida:ClientID"];
            string appKey          = ConfigurationManager.AppSettings["ida:Password"];
            string graphResourceID = "https://graph.windows.net";
            //fixed address for multitenant apps in the public cloud
            string Authority = "https://login.microsoftonline.com/common/";

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions {
            });

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                ClientId  = clientId,
                Authority = Authority,
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    // instead of using the default validation (validating against a single issuer value, as we do in line of business apps),
                    // we inject our own multitenant validation logic
                    ValidateIssuer = false,
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthorizationCodeReceived = async(context) =>
                    {
                        var code = context.Code;

                        ClientCredential credential = new ClientCredential(clientId, appKey);
                        string tenantID             = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                        string signedInUserID       = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;

                        AuthenticationContext authContext = new AuthenticationContext(string.Format("https://login.microsoftonline.com/{0}", tenantID), new EFADALTokenCache(signedInUserID));
                        AuthenticationResult result       = await authContext.AcquireTokenByAuthorizationCodeAsync(
                            code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceID);
                    },
                    RedirectToIdentityProvider = (context) =>
                    {
                        // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                        // this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
                        // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                        string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                        context.ProtocolMessage.RedirectUri           = appBaseUrl + "/";
                        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                        return(Task.FromResult(0));
                    },
                    // we use this notification for injecting our custom logic
                    SecurityTokenValidated = (context) =>
                    {
                        // retriever caller data from the incoming principal
                        string issuer   = context.AuthenticationTicket.Identity.FindFirst("iss").Value;
                        string UPN      = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
                        string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;

                        if (
                            // the caller comes from an admin-consented, recorded issuer
                            (db.Tenants.FirstOrDefault(a => ((a.IssValue == issuer) && (a.AdminConsented))) == null)
                            // the caller is recorded in the db of users who went through the individual onboardoing
                            && (db.Users.FirstOrDefault(b => ((b.UPN == UPN) && (b.TenantID == tenantID))) == null)
                            )
                        {
                            // the caller was neither from a trusted issuer or a registered user - throw to block the authentication flow
                            throw new System.IdentityModel.Tokens.SecurityTokenValidationException();
                        }
                        return(Task.FromResult(0));
                    },
                    AuthenticationFailed = (context) =>
                    {
                        context.OwinContext.Response.Redirect("/Home/Error");
                        context.HandleResponse();     // Suppress the exception
                        return(Task.FromResult(0));
                    }
                }
            });
        }
コード例 #6
0
        public async Task <ActionResult> Index(string code)
        {
            List <MyEvent> eventList = new List <MyEvent>();

            AuthenticationContext authContext = new AuthenticationContext(
                ConfigurationManager.AppSettings["ida:AuthorizationUri"] + "/common",
                true);

            ClientCredential creds = new ClientCredential(
                ConfigurationManager.AppSettings["ida:ClientID"],
                ConfigurationManager.AppSettings["ida:Password"]);

            DiscoveryClient           disco       = GetFromCache("DiscoveryClient") as DiscoveryClient;
            CapabilityDiscoveryResult eventsDisco = GetFromCache("EventsDiscovery") as CapabilityDiscoveryResult;

            //Redirect to login page if we do not have an
            //authorization code for the Discovery service
            if (disco == null && code == null)
            {
                Uri redirectUri = authContext.GetAuthorizationRequestURL(
                    discoResource,
                    creds.ClientId,
                    new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                    UserIdentifier.AnyUser,
                    string.Empty);

                return(Redirect(redirectUri.ToString()));
            }

            //Create a DiscoveryClient using the authorization code
            if (disco == null && code != null)
            {
                disco = new DiscoveryClient(new Uri(discoEndpoint), async() =>
                {
                    var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                        code,
                        new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                        creds);

                    return(authResult.AccessToken);
                });
            }

            if (disco != null && code != null & eventsDisco == null)
            {
                //Discover required capabilities
                eventsDisco = await disco.DiscoverCapabilityAsync("Calendar");

                SaveInCache("EventsDiscovery", eventsDisco);

                code = null;

                //Get authorization code for the calendar
                Uri redirectUri = authContext.GetAuthorizationRequestURL(
                    eventsDisco.ServiceResourceId,
                    creds.ClientId,
                    new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                    UserIdentifier.AnyUser,
                    string.Empty);

                return(Redirect(redirectUri.ToString()));
            }

            //Get the calendar events
            if (disco != null && code != null & eventsDisco != null)
            {
                OutlookServicesClient outlookClient = new OutlookServicesClient(eventsDisco.ServiceEndpointUri, async() =>
                {
                    var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                        code,
                        new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                        creds);

                    return(authResult.AccessToken);
                });

                //Get the events for the next 8 hours
                var eventResults = await(from i in outlookClient.Me.Events
                                         where i.End >= DateTimeOffset.UtcNow && i.End <= DateTimeOffset.UtcNow.AddHours(8)
                                         select i).Take(5).ExecuteAsync();
                var events = eventResults.CurrentPage.OrderBy(e => e.Start);

                foreach (var e in events)
                {
                    eventList.Add(new MyEvent
                    {
                        Id       = e.Id,
                        Body     = e.Body == null ? string.Empty : e.Body.Content,
                        End      = e.End,
                        Location = e.Location == null ? string.Empty : e.Location.DisplayName,
                        Start    = e.Start,
                        Subject  = e.Subject == null ? string.Empty : e.Subject
                    });
                }

                //cache the events
                SaveInCache("Events", eventList);
            }

            return(View());
        }
コード例 #7
0
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions {
                ClientId  = AADAppSettings.ClientId,
                Authority = AADAppSettings.Authority,

                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters {
                    // instead of using the default validation (validating against a single issuer value, as we do in line of business apps (single tenant apps)),
                    // we turn off validation
                    //
                    // NOTE:
                    // * In a multitenant scenario you can never validate against a fixed issuer string, as every tenant will send a different one.
                    // * If you don’t care about validating tenants, as is the case for apps giving access to 1st party resources, you just turn off validation.
                    // * If you do care about validating tenants, think of the case in which your app sells access to premium content and you want to limit access only to the tenant that paid a fee,
                    //       you still need to turn off the default validation but you do need to add logic that compares the incoming issuer to a list of tenants that paid you,
                    //       and block access if that’s not the case.
                    // * Refer to the following sample for a custom validation logic: https://github.com/AzureADSamples/WebApp-WebAPI-MultiTenant-OpenIdConnect-DotNet

                    ValidateIssuer = false
                },

                Notifications = new OpenIdConnectAuthenticationNotifications {
                    // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                    AuthorizationCodeReceived = async context => {
                        var serviceCredential = new ClientCredential(AADAppSettings.ClientId, AADAppSettings.AppKey);

                        string tenantID       = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                        string nameIdentifier = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;

                        AuthenticationContext authContext = new AuthenticationContext(
                            string.Format("{0}/{1}", AADAppSettings.AuthorizationUri, tenantID),
                            new SimpleTokenCache(nameIdentifier)
                            );

                        // Get the access token for AAD Graph. Doing this will also initialize the token cache associated with the authentication context
                        // In theory, you could acquire token for any service your application has access to here so that you can initialize the token cache
                        AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                            context.Code,
                            new Uri(context.Request.Uri.GetLeftPart(UriPartial.Path)),
                            serviceCredential,
                            AADAppSettings.SharePointResourceId
                            );

                        Debug.WriteLine("Auth result: {0}", result);
                    },

                    RedirectToIdentityProvider = (context) => {
                        // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                        // this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
                        // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                        string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                        context.ProtocolMessage.RedirectUri           = appBaseUrl + "/Home/App";
                        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;

                        return(Task.FromResult(0));
                    },

                    AuthenticationFailed = (context) => {
                        // Suppress the exception
                        context.HandleResponse();

                        return(Task.FromResult(0));
                    }
                }
            });
        }
コード例 #8
0
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1);

            var builder = services.AddIdentityServer()
                          .AddInMemoryIdentityResources(Config.GetIdentityResources())
                          .AddInMemoryApiResources(Config.GetApis())
                          .AddInMemoryClients(Config.GetClients());

            //services.AddOidcStateDataFormatterCache();

            //services.AddAuthentication().AddOAuth("AdfsOAuth", "EIMAS OAuth", options =>
            //{
            //    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
            //    options.SaveTokens = true;
            //    options.ClientId = "b33eb921-d242-4f1c-9892-3aa99fd59971";
            //    options.ClientSecret = "rssfJPdeWeTM8bmZRnV5kFyy_RcAQq5RJ_1vGtvo";
            //    options.AuthorizationEndpoint = "https://dev-connect.eurofins.local/adfs/oauth2/authorize";
            //    options.TokenEndpoint = "https://dev-connect.eurofins.local/adfs/oauth2/token";
            //    options.UserInformationEndpoint = "https://dev-connect.eurofins.local/adfs/userinfo";
            //    options.CallbackPath = "/signin-adfs";
            //    options.Scope.Add("openid");
            //    options.Scope.Add("profile");
            //    options.Scope.Add("allatclaims");
            //    options.Scope.Add("email");
            //    options.Scope.Add("http://*****:*****@me.com"));
                        //claims.Add(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/myclaim1", "value1"));
                        //claims.Add(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/myclaim2", "value2"));

                        //ctx.HttpContext.User.AddIdentity(new ClaimsIdentity(claims));

                        //ctx.Principal = new ClaimsPrincipal(ci);
                        // .Success() uses
                        // 1. the principal just set above
                        // 2. the context properties
                        // 3. the context scheme
                        // to create the underlying ticket
                        //ctx.Success();
                        await Task.FromResult(0);
                    },

                    OnAuthorizationCodeReceived = async ctx =>
                    {
                        var request    = ctx.HttpContext.Request;
                        var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
                        var credential = new ClientCredential(ctx.Options.ClientId, ctx.Options.ClientSecret);

                        var authContext = new AuthenticationContext(ctx.Options.Authority, false, new
                                                                    InMemoryTokenCache(ctx.Principal.Identity.Name));

                        var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                            ctx.ProtocolMessage.Code, new Uri(currentUri), credential, ctx.Options.Resource);

                        ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
                    }
                };
            });

            // DANGER : PRODUCTION MUST SIGN KEYS WITH A CERT!
            //if (Environment.IsDevelopment())
            {
                builder.AddDeveloperSigningCredential();
            }
            //else
            //{
            //    throw new Exception("need to configure key material");
            //}
        }
コード例 #9
0
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    
                    ClientId = clientId,
                    Authority = Authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        //
                        // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                        //
                        
                        AuthorizationCodeReceived = async (context) =>
                        {
                            var code = context.Code;

                            if ( certName.Length != 0)
                            {
                                // Create a Client Credential Using a Certificate
                                //
                                // Initialize the Certificate Credential to be used by ADAL.
                                // First find the matching certificate in the cert store.
                                //

                                X509Certificate2 cert = null;
                                X509Store store = new X509Store(StoreLocation.CurrentUser);
                                try
                                {
                                    store.Open(OpenFlags.ReadOnly);
                                    // Place all certificates in an X509Certificate2Collection object.
                                    X509Certificate2Collection certCollection = store.Certificates;
                                    // Find unexpired certificates.
                                    X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
                                    // From the collection of unexpired certificates, find the ones with the correct name.
                                    X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, false);
                                    if (signingCert.Count == 0)
                                    {
                                        // No matching certificate found.
                                        return;
                                    }
                                    // Return the first certificate in the collection, has the right name and is current.
                                    cert = signingCert[0];
                                }
                                finally
                                {
                                    store.Close();
                                }

                                // Then create the certificate credential.
                                ClientAssertionCertificate credential = new ClientAssertionCertificate(clientId, cert);

                                string userObjectID = context.AuthenticationTicket.Identity.FindFirst(
                                    "http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                                AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));
                                AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                                    code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
                                AuthenticationHelper.token = result.AccessToken;
                            }
                            else
                            {
                                // Create a Client Credential Using an Application Key
                                ClientCredential credential = new ClientCredential(clientId, appKey);
                                string userObjectID = context.AuthenticationTicket.Identity.FindFirst(
                                    "http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                                AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));
                                AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                                    code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
                                AuthenticationHelper.token = result.AccessToken;
                            }
                        }

                    }

                });
        }
コード例 #10
0
        public async Task <ActionResult> Contacts(string code)
        {
            AuthenticationContext authContext = new AuthenticationContext(
                ConfigurationManager.AppSettings["ida:AuthorizationUri"] + "/common",
                true);

            ClientCredential creds = new ClientCredential(
                ConfigurationManager.AppSettings["ida:ClientID"],
                ConfigurationManager.AppSettings["ida:Password"]);

            //Get the discovery information that was saved earlier
            CapabilityDiscoveryResult cdr = Helpers.GetFromCache("ContactsDiscoveryResult") as CapabilityDiscoveryResult;

            //Get a client, if this page was already visited
            OutlookServicesClient outlookClient = Helpers.GetFromCache("OutlookClient") as OutlookServicesClient;

            //Get an authorization code if needed
            if (outlookClient == null && cdr != null && code == null)
            {
                Uri redirectUri = authContext.GetAuthorizationRequestURL(
                    cdr.ServiceResourceId,
                    creds.ClientId,
                    new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                    UserIdentifier.AnyUser,
                    string.Empty);

                return(Redirect(redirectUri.ToString()));
            }

            //Create the OutlookServicesClient
            if (outlookClient == null && cdr != null && code != null)
            {
                outlookClient = new OutlookServicesClient(cdr.ServiceEndpointUri, async() =>
                {
                    var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                        code,
                        new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                        creds);

                    return(authResult.AccessToken);
                });

                Helpers.SaveInCache("OutlookClient", outlookClient);
            }

            //Get the contacts
            var contactsResults = await outlookClient.Me.Contacts.ExecuteAsync();

            List <MyContact> contactList = new List <MyContact>();

            foreach (var contact in contactsResults.CurrentPage.OrderBy(c => c.Surname))
            {
                contactList.Add(new MyContact
                {
                    Id             = contact.Id,
                    GivenName      = contact.GivenName,
                    Surname        = contact.Surname,
                    DisplayName    = contact.Surname + ", " + contact.GivenName,
                    CompanyName    = contact.CompanyName,
                    EmailAddress1  = contact.EmailAddresses.FirstOrDefault().Address,
                    BusinessPhone1 = contact.BusinessPhones.FirstOrDefault(),
                    HomePhone1     = contact.HomePhones.FirstOrDefault()
                });
            }

            //Save the contacts
            Helpers.SaveInCache("ContactList", contactList);

            //Show the contacts
            return(View(contactList));
        }
コード例 #11
0
        public async Task ConfidentialClientWithJwtTest()
        {
            var context = new AuthenticationContext(TestConstants.DefaultAuthorityCommonTenant, new TokenCache());

            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler()
            {
                Method          = HttpMethod.Post,
                ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(),
                PostData        = new Dictionary <string, string>()
                {
                    { "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" }
                }
            });

            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler()
            {
                Method          = HttpMethod.Post,
                ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(),
                PostData        = new Dictionary <string, string>()
                {
                    { "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" }
                }
            });

            ClientAssertion      assertion = new ClientAssertion(TestConstants.DefaultClientId, "some-assertion");
            AuthenticationResult result    = await context.AcquireTokenByAuthorizationCodeAsync("some-code", TestConstants.DefaultRedirectUri, assertion, TestConstants.DefaultResource);

            Assert.IsNotNull(result.AccessToken);

            result = await context.AcquireTokenByAuthorizationCodeAsync("some-code", TestConstants.DefaultRedirectUri, assertion, null);

            Assert.IsNotNull(result.AccessToken);

            try
            {
                await context.AcquireTokenByAuthorizationCodeAsync(string.Empty, TestConstants.DefaultRedirectUri, assertion, TestConstants.DefaultResource);
            }
            catch (ArgumentNullException exc)
            {
                Assert.AreEqual(exc.ParamName, "authorizationCode");
            }

            try
            {
                await context.AcquireTokenByAuthorizationCodeAsync(null, TestConstants.DefaultRedirectUri, assertion, TestConstants.DefaultResource);
            }
            catch (ArgumentNullException exc)
            {
                Assert.AreEqual(exc.ParamName, "authorizationCode");
            }

            try
            {
                await context.AcquireTokenByAuthorizationCodeAsync("some-code", null, assertion, TestConstants.DefaultResource);
            }
            catch (ArgumentNullException exc)
            {
                Assert.AreEqual(exc.ParamName, "redirectUri");
            }

            try
            {
                await context.AcquireTokenByAuthorizationCodeAsync("some-code", TestConstants.DefaultRedirectUri, (ClientAssertion)null, TestConstants.DefaultResource);
            }
            catch (ArgumentNullException exc)
            {
                Assert.AreEqual(exc.ParamName, "clientAssertion");
            }
        }
コード例 #12
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The service collection.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(opts =>
            {
                opts.Filters.Add(typeof(AdalTokenAcquisitionExceptionFilterAttribute));
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddDataProtection();

            // Wiring up App Insights
            services.AddApplicationInsightsTelemetry();
            services.AddSingleton <IKeyVaultHelper, KeyVaultHelper>();
            services.AddSingleton <AppSettings>();
            services.AddSingleton <IApiHelper, ApiHelper>();

            var serviceProvider = services.BuildServiceProvider();
            var appSettings     = serviceProvider.GetService <AppSettings>();

            // Add a strongly-typed options class to DI
            services.Configure <AuthOptionsModel>(opt =>
            {
                opt.Authority    = appSettings.Authority;
                opt.ClientId     = appSettings.ClientId;
                opt.ClientSecret = appSettings.ClientSecret;
            });

            services.AddScoped <ITokenCacheFactory, TokenCacheFactory>();

            services.AddStackExchangeRedisCache(options =>
            {
                options.Configuration = appSettings.RedisCacheConfiguration;
                options.InstanceName  = this.Configuration["RedisCacheInstanceName"];
            });

            services.AddHttpClient("ShiftsKronosIntegrationAPI", c =>
            {
                c.BaseAddress = new Uri(this.Configuration["BaseAddressFirstTimeSync"]);
                c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            }).AddPolicyHandler(GetRetryPolicy());

            services.AddHttpClient("GraphBetaAPI", client =>
            {
                client.BaseAddress = new Uri(this.Configuration["GraphApiUrl"]);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            }).AddPolicyHandler(GetRetryPolicy());

            services.AddAuthentication(auth =>
            {
                auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                auth.DefaultChallengeScheme    = OpenIdConnectDefaults.AuthenticationScheme;
                auth.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie(opts =>
            {
                opts.SlidingExpiration = true;
                opts.AccessDeniedPath  = new PathString("/Account/AccessDenied");
            })
            .AddOpenIdConnect(
                opts =>
            {
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
                opts.Events.OnTicketReceived = async(context) =>
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
                {
                    context.Properties.ExpiresUtc = DateTime.UtcNow.AddHours(1);
                };

                opts.ClientId     = this.Configuration["ClientId"];
                opts.ClientSecret = this.Configuration["ClientSecret"];
                opts.Authority    = this.Configuration["Authority"];
                opts.ResponseType = this.Configuration["ResponseType"];

                this.Configuration.Bind(opts);
                opts.TokenValidationParameters.ValidateIssuer = false;
                opts.Events = new OpenIdConnectEvents
                {
                    OnAuthorizationCodeReceived = async ctx =>
                    {
                        HttpRequest request = ctx.HttpContext.Request;

                        // We need to also specify the redirect URL used
                        string currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);

                        // Credentials for app itself
                        var credential = new ClientCredential(appSettings.ClientId, appSettings.ClientSecret);

                        // Construct token cache
                        var distributedCache = ctx.HttpContext.RequestServices.GetRequiredService <IDistributedCache>();
                        var cache            = new RedisTokenCache(distributedCache, appSettings.ClientId);

                        var authContext = new AuthenticationContext("https://login.microsoftonline.com/common", cache);

                        // Get token for Microsoft Graph API using the authorization code
                        string resource             = "https://graph.microsoft.com";
                        AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                            ctx.ProtocolMessage.Code, new Uri(currentUri), credential, resource).ConfigureAwait(false);

                        // Tell the OIDC middleware we got the tokens, it doesn't need to do anything
                        ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
                    },
                };
            });

            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddOptions();
            services.AddHttpClient();

            // As each sub-integration is being implemented, we need to make sure that we can correctly setup the DI.g
            services.AddSingleton <BusinessLogic.Providers.IConfigurationProvider>((provider) => new BusinessLogic.Providers.ConfigurationProvider(
                                                                                       appSettings.StorageConnectionString,
                                                                                       provider.GetRequiredService <TelemetryClient>()));
            services.AddSingleton <ITeamDepartmentMappingProvider>((provider) => new TeamDepartmentMappingProvider(
                                                                       appSettings.StorageConnectionString,
                                                                       provider.GetRequiredService <TelemetryClient>()));
            services.AddSingleton <IUserMappingProvider>((provider) => new UserMappingProvider(
                                                             appSettings.StorageConnectionString,
                                                             provider.GetRequiredService <TelemetryClient>()));
            services.AddSingleton <IGraphUtility>((provider) => new GraphUtility(
                                                      provider.GetRequiredService <TelemetryClient>(),
                                                      provider.GetRequiredService <IDistributedCache>(),
                                                      provider.GetRequiredService <System.Net.Http.IHttpClientFactory>()));
            services.AddSingleton <ShiftsTeamKronosDepartmentViewModel>();
            services.AddSingleton <IShiftMappingEntityProvider>((provider) => new ShiftMappingEntityProvider(
                                                                    provider.GetRequiredService <TelemetryClient>(),
                                                                    appSettings.StorageConnectionString));
            services.AddSingleton <IOpenShiftMappingEntityProvider>((provider) => new OpenShiftMappingEntityProvider(
                                                                        provider.GetRequiredService <TelemetryClient>(),
                                                                        appSettings.StorageConnectionString));
            services.AddSingleton <ITimeOffMappingEntityProvider>((provider) => new TimeOffMappingEntityProvider(
                                                                      provider.GetRequiredService <TelemetryClient>(),
                                                                      appSettings.StorageConnectionString));
            services.AddSingleton <IAzureTableStorageHelper>((provider) => new AzureTableStorageHelper(
                                                                 appSettings.StorageConnectionString,
                                                                 provider.GetRequiredService <TelemetryClient>()));
            services.AddSingleton((provider) => new Utility(
                                      provider.GetRequiredService <TelemetryClient>(),
                                      provider.GetRequiredService <ILogonActivity>(),
                                      provider.GetRequiredService <AppSettings>(),
                                      provider.GetRequiredService <IDistributedCache>(),
                                      provider.GetRequiredService <BusinessLogic.Providers.IConfigurationProvider>(),
                                      provider.GetRequiredService <IAzureTableStorageHelper>(),
                                      provider.GetRequiredService <IGraphUtility>()));

            services.AddSingleton((provider) => new TeamDepartmentMappingController(
                                      provider.GetRequiredService <ITeamDepartmentMappingProvider>(),
                                      provider.GetRequiredService <TelemetryClient>(),
                                      provider.GetRequiredService <ILogonActivity>(),
                                      provider.GetRequiredService <IHyperFindLoadAllActivity>(),
                                      provider.GetRequiredService <ShiftsTeamKronosDepartmentViewModel>(),
                                      provider.GetRequiredService <Utility>(),
                                      provider.GetRequiredService <IGraphUtility>(),
                                      provider.GetRequiredService <AppSettings>(),
                                      provider.GetRequiredService <BusinessLogic.Providers.IConfigurationProvider>(),
                                      provider.GetRequiredService <IDistributedCache>(),
                                      provider.GetRequiredService <IUserMappingProvider>(),
                                      provider.GetRequiredService <System.Net.Http.IHttpClientFactory>()));

            services.AddSingleton((provider) => new UserMappingController(
                                      provider.GetRequiredService <AppSettings>(),
                                      provider.GetRequiredService <IGraphUtility>(),
                                      provider.GetRequiredService <ILogonActivity>(),
                                      provider.GetRequiredService <IHyperFindActivity>(),
                                      provider.GetRequiredService <TelemetryClient>(),
                                      provider.GetRequiredService <IUserMappingProvider>(),
                                      provider.GetRequiredService <ITeamDepartmentMappingProvider>(),
                                      provider.GetRequiredService <BusinessLogic.Providers.IConfigurationProvider>(),
                                      provider.GetRequiredService <IJobAssignmentActivity>(),
                                      provider.GetRequiredService <IHostingEnvironment>(),
                                      provider.GetRequiredService <Utility>()));

            // Wiring up Kronos dependency chain to set up DI container.
            services.AddSingleton <App.KronosWfc.Models.RequestEntities.Logon.Request>();
            services.AddSingleton <ILogonActivity, LogonActivity>((provider) => new LogonActivity(
                                                                      new App.KronosWfc.Models.RequestEntities.Logon.Request(),
                                                                      provider.GetRequiredService <TelemetryClient>(),
                                                                      provider.GetRequiredService <IApiHelper>()));
            services.AddSingleton <IHyperFindLoadAllActivity, HyperFindLoadAllActivity>((provider) => new HyperFindLoadAllActivity(
                                                                                            provider.GetRequiredService <TelemetryClient>(),
                                                                                            provider.GetRequiredService <IApiHelper>()));
            services.AddSingleton <IHyperFindActivity, HyperFindActivity>((provider) => new HyperFindActivity(
                                                                              provider.GetRequiredService <TelemetryClient>(),
                                                                              provider.GetRequiredService <IApiHelper>()));
            services.AddSingleton <IJobAssignmentActivity, JobAssignmentActivity>((provider) => new JobAssignmentActivity(
                                                                                      provider.GetRequiredService <TelemetryClient>(),
                                                                                      provider.GetRequiredService <IApiHelper>()));
        }
コード例 #13
0
        protected async void Page_Load(object sender, EventArgs e)
        {
            try
            {
                ClientCredential credential = new ClientCredential(Constants.AzureActiveDirectory.ClientId,
                                                                   Constants.AzureActiveDirectory.AppKey);


                var authContext =
                    new AuthenticationContext(string.Format(Constants.AzureActiveDirectory.Authority,
                                                            Constants.AzureActiveDirectory.TenantId));
                var code = ValidationHelper.GetString(HttpContext.Current.Request.QueryString["code"], string.Empty);
                AuthenticationResult result =
                    await
                    authContext.AcquireTokenByAuthorizationCodeAsync(code,
                                                                     new Uri(Request.Url.GetLeftPart(UriPartial.Path)), credential,
                                                                     string.Format(Constants.AzureActiveDirectory.GraphResourceUri, ""));

                var adClient = new ActiveDirectoryClient(
                    new Uri(string.Format(Constants.AzureActiveDirectory.GraphResourceUri, result.TenantId)),
                    async() => await GetAppTokenAsync(result.TenantId));
                var adUser =
                    (User)
                    await
                    adClient.Users.Where(x => x.UserPrincipalName.Equals(result.UserInfo.DisplayableId))
                    .Expand(x => x.MemberOf)
                    .ExecuteSingleAsync();

                var user =
                    UserInfoProvider.GetUsers()
                    .Where("AzureADUsername", QueryOperator.Equals, adUser.UserPrincipalName)
                    .FirstOrDefault();
                var groupsToAdd = adUser.MemberOf.OfType <Group>()
                                  .Select(x => x.DisplayName)
                                  .Where(x => Constants.AzureActiveDirectory.GroupsToSync.Contains(x));
                var groupsToRemove = Constants.AzureActiveDirectory.GroupsToSync
                                     .Where(x => !groupsToAdd.Contains(x));
                if (user == null)
                {
                    user           = new CMS.Membership.UserInfo();
                    user.UserName  = adUser.UserPrincipalName;
                    user.FirstName = adUser.GivenName;
                    user.LastName  = adUser.Surname;
                    user.FullName  = adUser.DisplayName;
                    user.Email     = adUser.Mail.IfEmpty(adUser.OtherMails.FirstOrDefault());
                    user.SetValue("AzureADUsername", adUser.UserPrincipalName);
                    user.IsExternal = true;
                    user.Enabled    = true;
                    UserInfoProvider.SetUserInfo(user);
                    UserInfoProvider.AddUserToSite(user.UserName, SiteContext.CurrentSiteName);

                    foreach (var group in groupsToAdd)
                    {
                        UserInfoProvider.AddUserToRole(user.UserName,
                                                       RoleInfoProvider.GetRoles()
                                                       .OnSite(SiteContext.CurrentSiteID)
                                                       .Where("RoleDisplayName", QueryOperator.Equals, group)
                                                       .FirstOrDefault()?.RoleName ?? "", SiteContext.CurrentSiteName);
                    }
                }
                else
                {
                    user.FirstName  = adUser.GivenName;
                    user.LastName   = adUser.Surname;
                    user.FullName   = adUser.DisplayName;
                    user.Email      = adUser.Mail.IfEmpty(adUser.OtherMails.FirstOrDefault());
                    user.IsExternal = true;
                    UserInfoProvider.SetUserInfo(user);
                    UserInfoProvider.AddUserToSite(user.UserName, SiteContext.CurrentSiteName);
                    foreach (var group in groupsToAdd)
                    {
                        UserInfoProvider.AddUserToRole(user.UserName,
                                                       RoleInfoProvider.GetRoles()
                                                       .OnSite(SiteContext.CurrentSiteID)
                                                       .Where("RoleDisplayName", QueryOperator.Equals, group)
                                                       .FirstOrDefault()?.RoleName ?? "", SiteContext.CurrentSiteName);
                    }

                    foreach (var group in groupsToRemove)
                    {
                        UserInfoProvider.RemoveUserFromRole(user.UserName,
                                                            RoleInfoProvider.GetRoles()
                                                            .OnSite(SiteContext.CurrentSiteID)
                                                            .Where("RoleDisplayName", QueryOperator.Equals, group)
                                                            .FirstOrDefault()?.RoleName ?? "", SiteContext.CurrentSiteName);
                    }
                }

                AuthenticationHelper.AuthenticateUser(user.UserName, false);
                MembershipActivityLogger.LogLogin(user.UserName, DocumentContext.CurrentDocument);
            }
            catch (Exception exception)
            {
                EventLogProvider.LogException("AzureActiveDirectory", "Login", exception);
            }

            var postLoginPage = DocumentHelper.GetDocuments()
                                .WhereEquals("NodeAliasPath", Constants.AzureActiveDirectory.PostLoginPage)
                                .FirstOrDefault(x => x.DocumentCulture.Equals(LocalizationContext.CurrentCulture.CultureCode,
                                                                              StringComparison.InvariantCultureIgnoreCase));
            var returnUrl = HttpContext.Current.Request.GetReturnUrl(postLoginPage.GetRelativeUrl());

            URLHelper.Redirect(URLHelper.GetAbsoluteUrl(returnUrl));
        }
コード例 #14
0
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                ClientId  = clientId,
                Authority = authority,
                //PostLogoutRedirectUri = postLogoutRedirectUri, **Will be set dynamically later
                Resource      = resource,
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthenticationFailed = (context) =>
                    {
                        //This section added to handle scenario where user logs in, but cancels consenting to rights to read directory profile
                        //Sometimes the Consent Framework doesn't kick in so this code is also executed in that sitiation. The user is redirected to the log out page
                        string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                        context.ProtocolMessage.RedirectUri = appBaseUrl + postLogoutRedirectUri;
                        context.HandleResponse();
                        context.Response.Redirect(context.ProtocolMessage.RedirectUri);
                        return(System.Threading.Tasks.Task.FromResult(0));
                    },
                    RedirectToIdentityProvider = (context) =>
                    {
                        //Dynamically set RedirectUri & PostLogoutRedirectUri
                        string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                        context.ProtocolMessage.RedirectUri           = appBaseUrl + "/";
                        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl + postLogoutRedirectUri;
                        //context.ProtocolMessage.Prompt = "admin_consent";
                        return(System.Threading.Tasks.Task.FromResult(0));
                    },
                    AuthorizationCodeReceived = async(context) =>
                    {
                        var code = context.Code;
                        //ClientCredential credential = new ClientCredential(clientId, clientSecret);
                        ClientAssertionCertificate credential = new ClientAssertionCertificate(clientId, cert);

                        //string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                        var userObjectId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                        string tenantId  = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                        //System.Security.Claims.ClaimsPrincipal claimsPrincipal = System.Security.Claims.ClaimsPrincipal.Current;

                        AuthenticationContext authContext = new AuthenticationContext(aadInstance + tenantId, new Utils.EFADALTokenCache($"{tenantId}:{userObjectId}"));
                        AuthenticationResult result       = await authContext.AcquireTokenByAuthorizationCodeAsync(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, resource);
                        result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, webApiResource);
                    }
                },
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidateIssuer = false,
                    //RoleClaimType = "groups",
                    //SaveSigninToken = true
                }
            }

                );

            // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
            app.UseStageMarker(PipelineStage.Authenticate);
        }
コード例 #15
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(OpcVaultOptions);
            services.AddSingleton(AzureADOptions);

            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options => Configuration.Bind("AzureAd", options))
            ;
            services.Configure <OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
            {
                // Without overriding the response type (which by default is id_token), the OnAuthorizationCodeReceived event is not called.
                // but instead OnTokenValidated event is called. Here we request both so that OnTokenValidated is called first which
                // ensures that context.Principal has a non-null value when OnAuthorizeationCodeReceived is called
                options.ResponseType = "id_token code";
                // set the resource id of the service api which needs to be accessed
                options.Resource = OpcVaultOptions.ResourceId;
                // refresh token
                options.Scope.Add("offline_access");

                options.Events = new OpenIdConnectEvents
                {
                    OnTicketReceived = context =>
                    {
                        // stop by `/Home/Continue` instead of going directly to the ReturnUri
                        // to work around Safari's issues with SameSite=lax session cookies not being
                        // returned on the final redirect of the authentication flow.
                        // credits:
                        // https://community.auth0.com/t/authentication-broken-on-asp-net-core-and-safari-on-ios-12-mojave-take-2/19104
                        context.ReturnUri = "/Home/Continue?returnUrl=" + System.Net.WebUtility.UrlEncode(context.ReturnUri ?? "/");
                        return(Task.CompletedTask);
                    },
                    OnAuthenticationFailed = context =>
                    {
                        context.Response.Redirect("/Error");
                        context.HandleResponse(); // Suppress the exception
                        return(Task.CompletedTask);
                    },
                    /// <summary>
                    /// Redeems the authorization code by calling AcquireTokenByAuthorizationCodeAsync in order to ensure
                    /// that the cache has a token for the signed-in user, which will then enable the controllers
                    /// to call AcquireTokenSilentAsync successfully.
                    /// </summary>
                    OnAuthorizationCodeReceived = async context =>
                    {
                        // Acquire a Token for the API and cache it. In the OpcVaultController, we'll use the cache to acquire a token for the API
                        string userObjectId = (context.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
                        var credential      = new ClientCredential(context.Options.ClientId, context.Options.ClientSecret);

                        var tokenCacheService = context.HttpContext.RequestServices.GetRequiredService <ITokenCacheService>();
                        var tokenCache        = await tokenCacheService.GetCacheAsync(context.Principal);
                        var authContext       = new AuthenticationContext(context.Options.Authority, tokenCache);

                        var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(context.TokenEndpointRequest.Code,
                                                                                                new Uri(context.TokenEndpointRequest.RedirectUri, UriKind.RelativeOrAbsolute), credential, context.Options.Resource);

                        // Notify the OIDC middleware that we already took care of code redemption.
                        context.HandleCodeRedemption(authResult.AccessToken, context.ProtocolMessage.IdToken);
                    },
                    // If your application needs to do authenticate single users, add your user validation below.
                    //OnTokenValidated = context =>
                    //{
                    //    return myUserValidationLogic(context.Ticket.Principal);
                    //}
                };
            });

            services.AddMvc(options =>
            {
                options.Filters.Add(typeof(AdalTokenAcquisitionExceptionFilter));
                var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddSession();

            services.AddApplicationInsightsTelemetry(Configuration);

            // This will register IDistributedCache based token cache which ADAL will use for caching access tokens.
            services.AddScoped <ITokenCacheService, DistributedTokenCacheService>();

            //http://stackoverflow.com/questions/37371264/asp-net-core-rc2-invalidoperationexception-unable-to-resolve-service-for-type/37373557
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            // Prepare DI container
            ApplicationContainer = ConfigureContainer(services);

            // Create the IServiceProvider based on the container
            return(new AutofacServiceProvider(ApplicationContainer));
        }
コード例 #16
0
        public async Task <IActionResult> OnGet()
        {
            //System.Diagnostics.Debug.WriteLine("\n_Host Get");

            Fs.Data.Models.AppContext appContext = Fs.Data.Models.AppContext.Instance;
            string authScheme = null;

            string referer = HttpContext.Request.Headers["Referer"];

            if (referer != null && referer.Length > 0)
            {
                _providerIndex = IdentityProvider.GetProviderIndexByAuthority(referer);
                if (_providerIndex == -1)
                {
                    _providerIndex = 0;
                    return(Page());
                }

                authScheme = appContext.AuthSchemes[_providerIndex].AuthScheme;
            }
            else
            {
                bool isAuthenticated = HttpContext.User.Identity.IsAuthenticated;
                if (isAuthenticated)
                {
                    string identityProvider = HttpContext.User.Claims
                                              .Where(c => c.Type.Equals(AuthenticationDefaults.ProviderKey))
                                              .Select(c => c.Value)
                                              .FirstOrDefault() ?? string.Empty;

                    authScheme = IdentityProvider.GetAuthenticationScheme(identityProvider);

                    _providerIndex = IdentityProvider.GetProviderIndexByScheme(authScheme);
                }
            }

            if (authScheme == null)
            {
                return(Page());
            }

            if (_providerIndex == -1)
            {
                // something went wrong
                throw new Exception("HostAuthModel: authentication scheme '" + authScheme + "' isn't initialized in app context.");
            }

            var authResult = await HttpContext.AuthenticateAsync(authScheme);

            if (authResult.Succeeded)
            {
                _expiration = authResult.Properties.ExpiresUtc.Value;

                if (authScheme == AzureADDefaults.AuthenticationScheme)
                {
                    var refererUri = HttpContext.Request.Headers["Referer"];

                    if (refererUri == appContext.AuthSchemes[_providerIndex].Authority)
                    {
                        if (HttpContext.Request.Query.Count == 0)
                        {
                            var @params = new NameValueCollection
                            {
                                // Azure AD will return an authorization code.
                                { "response_type", appContext.AuthSchemes[_providerIndex].ResponseType },
                                // You get the client id when you register your Azure client app.
                                { "client_id", appContext.AuthSchemes[_providerIndex].ClientId },
                                // You get the resource URI (client id) when you register your Azure API app.
                                { "resource", appContext.AuthSchemes[_providerIndex].ResourceId },
                                //After user authenticates, Azure AD will redirect back to the web app
                                { "redirect_uri", appContext.RedirectUri }
                            };

                            //Create sign-in query string
                            var queryString = HttpUtility.ParseQueryString(string.Empty);
                            queryString.Add(@params);

                            // Redirect to authority
                            var authorityUri = String.Format("{0}{1}{2}?{3}",
                                                             appContext.AuthSchemes[_providerIndex].Authority,
                                                             appContext.AuthSchemes[_providerIndex].TenantId,
                                                             appContext.AuthSchemes[_providerIndex].AuthorizePath, queryString);
                            Response.Redirect(authorityUri);
                        }
                        else
                        {
                            string authorityUri = String.Format("{0}{1}",
                                                                appContext.AuthSchemes[_providerIndex].Authority,
                                                                appContext.AuthSchemes[_providerIndex].TenantId);

                            // Get the auth code
                            string code = Request.Query[appContext.AuthSchemes[_providerIndex].CodeField];

                            // Get auth token from auth code
                            TokenCache tokenCache = new TokenCache();

                            AuthenticationContext authContext = new AuthenticationContext(authorityUri, tokenCache);

                            ClientCredential clientCredential = new ClientCredential(appContext.AuthSchemes[_providerIndex].ClientId,
                                                                                     appContext.AuthSchemes[_providerIndex].ClientSecret);

                            AuthenticationResult aResult = await authContext.AcquireTokenByAuthorizationCodeAsync(code, new Uri(appContext.RedirectUri), clientCredential);

                            _accessToken = aResult.AccessToken;
                        }
                    }
                }
                else if (authScheme == OpenIdDefaults.ChallengeScheme)
                {
                    var refererUri = HttpContext.Request.Headers["Referer"];
                    _accessToken = await HttpContext.GetTokenAsync("access_token");

                    _refreshToken = await HttpContext.GetTokenAsync("refresh_token");
                }
            }

            return(Page());
        }
コード例 #17
0
        public async Task <ActionResult> Projects(ViewModel submitModel, string code)
        {
            //If the New Project form needs to be displayed
            if (submitModel.Project == null && code == null)
            {
                ViewModel formModel = new ViewModel();
                formModel.Contacts = Helpers.GetFromCache("ContactList") as List <MyContact>;
                formModel.Files    = Helpers.GetFromCache("FileList") as List <MyFile>;
                return(View(formModel));
            }
            // A new project was submitted
            else
            {
                if (submitModel.Project != null)
                {
                    Helpers.SaveInCache("SubmitModel", submitModel);
                }

                AuthenticationContext authContext = new AuthenticationContext(
                    ConfigurationManager.AppSettings["ida:AuthorizationUri"] + "/common",
                    true);

                ClientCredential creds = new ClientCredential(
                    ConfigurationManager.AppSettings["ida:ClientID"],
                    ConfigurationManager.AppSettings["ida:Password"]);

                //Get an authorization code, if necessary
                if (code == null)
                {
                    Uri redirectUri = authContext.GetAuthorizationRequestURL(
                        spSite,
                        creds.ClientId,
                        new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                        UserIdentifier.AnyUser,
                        string.Empty);

                    return(Redirect(redirectUri.ToString()));
                }
                else
                {
                    //Get the access token
                    var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                        code,
                        new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                        creds);

                    string accessToken = authResult.AccessToken;

                    //Build SharePoint RESTful API endpoint for the list items
                    StringBuilder requestUri = new StringBuilder()
                                               .Append(spSite)
                                               .Append("/_api/web/lists/getbyTitle('Research Projects')/items");

                    //Create an XML message with the new project data
                    //This message will be POSTED to the SharePoint API endpoint
                    XNamespace atom = "http://www.w3.org/2005/Atom";
                    XNamespace d    = "http://schemas.microsoft.com/ado/2007/08/dataservices";
                    XNamespace m    = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";

                    submitModel = Helpers.GetFromCache("SubmitModel") as ViewModel;
                    string description = (Helpers.GetFromCache("FileList") as List <MyFile>).Where(f => f.Url == submitModel.Project.DocumentLink).First().Name;
                    string url         = submitModel.Project.DocumentLink;
                    string title       = submitModel.Project.Title;
                    string owner       = submitModel.Project.Owner;

                    XElement message = new XElement(atom + "entry",
                                                    new XAttribute(XNamespace.Xmlns + "d", d),
                                                    new XAttribute(XNamespace.Xmlns + "m", m),
                                                    new XElement(atom + "category", new XAttribute("term", "SP.Data.Research_x0020_ProjectsListItem"), new XAttribute("scheme", "http://schemas.microsoft.com/ado/2007/08/dataservices/scheme")),
                                                    new XElement(atom + "content", new XAttribute("type", "application/xml"),
                                                                 new XElement(m + "properties",
                                                                              new XElement(d + "Statement", new XAttribute(m + "type", "SP.FieldUrlValue"),
                                                                                           new XElement(d + "Description", description),
                                                                                           new XElement(d + "Url", url)),
                                                                              new XElement(d + "Title", title),
                                                                              new XElement(d + "Owner", owner))));

                    StringContent requestData = new StringContent(message.ToString());

                    //POST the data to the endpoint
                    HttpClient         client  = new HttpClient();
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri.ToString());
                    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
                    request.Headers.Authorization   = new AuthenticationHeaderValue("Bearer", accessToken);
                    requestData.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/atom+xml");
                    request.Content = requestData;
                    HttpResponseMessage response = await client.SendAsync(request);

                    //Show the Finished screen
                    return(RedirectToAction("Finished"));
                }
            }
        }
コード例 #18
0
        public async Task <ActionResult> Index(string code)
        {
            AuthenticationContext authContext = new AuthenticationContext(
                ConfigurationManager.AppSettings["ida:AuthorizationUri"] + "/common",
                true);

            ClientCredential creds = new ClientCredential(
                ConfigurationManager.AppSettings["ida:ClientID"],
                ConfigurationManager.AppSettings["ida:Password"]);

            DiscoveryClient disco = Helpers.GetFromCache("DiscoveryClient") as DiscoveryClient;

            //Redirect to login page if we do not have an
            //authorization code for the Discovery service
            if (disco == null && code == null)
            {
                Uri redirectUri = authContext.GetAuthorizationRequestURL(
                    discoResource,
                    creds.ClientId,
                    new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                    UserIdentifier.AnyUser,
                    string.Empty);

                return(Redirect(redirectUri.ToString()));
            }

            //Create a DiscoveryClient using the authorization code
            if (disco == null && code != null)
            {
                disco = new DiscoveryClient(new Uri(discoEndpoint), async() =>
                {
                    var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                        code,
                        new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                        creds);

                    return(authResult.AccessToken);
                });
            }

            //Discover required capabilities
            CapabilityDiscoveryResult contactsDisco = await disco.DiscoverCapabilityAsync("Contacts");

            CapabilityDiscoveryResult filesDisco = await disco.DiscoverCapabilityAsync("MyFiles");

            Helpers.SaveInCache("ContactsDiscoveryResult", contactsDisco);
            Helpers.SaveInCache("FilesDiscoveryResult", filesDisco);

            List <MyDiscovery> discoveries = new List <MyDiscovery>()
            {
                new MyDiscovery()
                {
                    Capability  = "Contacts",
                    EndpointUri = contactsDisco.ServiceEndpointUri.OriginalString,
                    ResourceId  = contactsDisco.ServiceResourceId,
                    Version     = contactsDisco.ServiceApiVersion
                },
                new MyDiscovery()
                {
                    Capability  = "My Files",
                    EndpointUri = filesDisco.ServiceEndpointUri.OriginalString,
                    ResourceId  = filesDisco.ServiceResourceId,
                    Version     = filesDisco.ServiceApiVersion
                }
            };

            return(View(discoveries));
        }
コード例 #19
0
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            // anstatt die Standardüberprüfung (Überprüfung anhand eines Ausstellerwerts wie in Branchen-Apps) zu verwenden,
            // wird eigene mehrinstanzenfähige Überprüfungslogik eingefügt
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                ClientId  = clientId,
                Authority = authority,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                    // Wenn die App Zugriff auf die gesamte Organisation benötigt, dann fügen Sie die Logik
                    // zum Überprüfen des Ausstellers hier ein.
                    // IssuerValidator
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    SecurityTokenValidated = (context) =>
                    {
                        // Wenn Ihre Authentifizierungslogik auf Benutzern basiert,
                        return(Task.FromResult(0));
                    },

                    AuthorizationCodeReceived = (context) =>
                    {
                        var code = context.Code;
                        var ctx  = context.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase;
                        var s    = ctx.Session;
                        ClientCredential credential = new ClientCredential(clientId, appKey);
                        string tenantID             = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                        string signedInUserID       = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;

                        AuthenticationContext authContext = new AuthenticationContext(aadInstance + tenantID, new ADALTokenCache(signedInUserID));
                        AuthenticationResult result       = authContext.AcquireTokenByAuthorizationCodeAsync(
                            code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId).Result;

                        return(Task.FromResult(0));
                    }
                }
            });

            // Auf diese Weise wird Middleware, die oberhalb dieser Zeile definiert ist, ausgeführt, bevor die Autorisierungsregel in "web.config" angewendet wird.
            app.UseStageMarker(PipelineStage.Authenticate);


//überflüssig
            //app.Use((context, next) =>
            //{
            //    var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
            //    httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
            //    return next();
            //});

            //// To make sure the above `Use` is in the correct position:
            //app.UseStageMarker(PipelineStage.AcquireState);
        }
        public override async Task ProcessRequestAsync(HttpContext context)
        {
            try
            {
                ClientCredential credential = new ClientCredential(Constants.AzureActiveDirectory.ClientId,
                                                                   Constants.AzureActiveDirectory.ApplicationKey);


                var authContext =
                    new AuthenticationContext(string.Format(Constants.AzureActiveDirectory.AuthorityUrl,
                                                            Constants.AzureActiveDirectory.TenantId));
                var code = ValidationHelper.GetString(HttpContext.Current.Request.QueryString["code"], string.Empty);
                AuthenticationResult result =
                    await
                    authContext.AcquireTokenByAuthorizationCodeAsync(code,
                                                                     new Uri(Request.Url.GetLeftPart(UriPartial.Path)), credential,
                                                                     string.Format(Constants.AzureActiveDirectory.GraphUrl, ""));

                var adClient = new ActiveDirectoryClient(
                    new Uri(string.Format(Constants.AzureActiveDirectory.GraphUrl, result.TenantId)),
                    async() => await GetAppTokenAsync(result.TenantId));

                var adUser =
                    (User)
                    await
                    adClient.Users.Where(x => x.UserPrincipalName.Equals(result.UserInfo.DisplayableId))
                    .Expand(x => x.MemberOf)
                    .ExecuteSingleAsync();

                var user =
                    UserInfoProvider.GetUsers()
                    .Where("AzureADUsername", QueryOperator.Equals, adUser.UserPrincipalName)
                    .FirstOrDefault();
                var groupsToAdd = adUser.MemberOf.OfType <Group>()
                                  .Select(x => x.DisplayName)
                                  .Where(x => Constants.AzureActiveDirectory.GroupsToSync.Contains(x));
                var groupsToRemove = Constants.AzureActiveDirectory.GroupsToSync
                                     .Where(x => !groupsToAdd.Contains(x));

                // check if any of the Azure Active Directory groups are matching by name any Kentico roles
                // if not save an error message in ErrorLog and return
                bool isGroupMatchRole = false;
                foreach (var group in groupsToAdd)
                {
                    var roleInfo = RoleInfoProvider.GetRoles()
                                   .OnSite(SiteContext.CurrentSiteID)
                                   .Where("RoleDisplayName", QueryOperator.Equals, group).ToList <RoleInfo>();
                    if (roleInfo.Count > 0)
                    {
                        isGroupMatchRole = true;
                        break;
                    }
                }

                if (!isGroupMatchRole)
                {
                    var logerr = $"Attempted login on {DateTime.Now} by user {adUser.UserPrincipalName},[{adUser.DisplayName}] memberOf {groupsToAdd.ToList<string>().Join(",")}";

                    EventLogProvider.LogEvent(EventType.ERROR,
                                              "Login user through Azure Active Directory",
                                              "AZUREADLOGINFAILURE",
                                              eventDescription: logerr);
                    var returnUrlWithError = ValidationHelper.GetString(this.Context.Request.Params["state"], string.Empty);
                    URLHelper.Redirect(URLHelper.GetAbsoluteUrl($"{returnUrlWithError}?logonresult=Failed&firstname={adUser.DisplayName}&lastname={string.Empty}&lastlogoninfo={logerr}"));
                    return;
                }

                if (user == null)
                {
                    user           = new CMS.Membership.UserInfo();
                    user.UserName  = adUser.UserPrincipalName;
                    user.FirstName = adUser.GivenName;
                    user.LastName  = adUser.Surname;
                    user.FullName  = adUser.DisplayName;
                    user.Email     = adUser.Mail.IfEmpty(adUser.OtherMails.FirstOrDefault());
                    user.SetValue("AzureADUsername", adUser.UserPrincipalName);
                    user.IsExternal = true;

                    //None		    0	User has no privilege level
                    //Editor		1	User is able to use administration interface
                    //Admin		    2	User can use all applications except the global applications and functionality
                    //GlobalAdmin	3	User can use all applications and functionality without any exceptions
                    user.SiteIndependentPrivilegeLevel = CMS.Base.UserPrivilegeLevelEnum.Editor;

                    user.Enabled = true;
                    UserInfoProvider.SetUserInfo(user);
                    UserInfoProvider.AddUserToSite(user.UserName, SiteContext.CurrentSiteName);

                    foreach (var group in groupsToAdd)
                    {
                        UserInfoProvider.AddUserToRole(user.UserName,
                                                       RoleInfoProvider.GetRoles()
                                                       .OnSite(SiteContext.CurrentSiteID)
                                                       .Where("RoleDisplayName", QueryOperator.Equals, group)
                                                       .FirstOrDefault()?.RoleName ?? "", SiteContext.CurrentSiteName);
                    }
                }
                else
                {
                    user.FirstName  = adUser.GivenName;
                    user.LastName   = adUser.Surname;
                    user.FullName   = adUser.DisplayName;
                    user.Email      = adUser.Mail.IfEmpty(adUser.OtherMails.FirstOrDefault());
                    user.IsExternal = true;
                    UserInfoProvider.SetUserInfo(user);
                    UserInfoProvider.AddUserToSite(user.UserName, SiteContext.CurrentSiteName);
                    foreach (var group in groupsToAdd)
                    {
                        UserInfoProvider.AddUserToRole(user.UserName,
                                                       RoleInfoProvider.GetRoles()
                                                       .OnSite(SiteContext.CurrentSiteID)
                                                       .Where("RoleDisplayName", QueryOperator.Equals, group)
                                                       .FirstOrDefault()?.RoleName ?? "", SiteContext.CurrentSiteName);
                    }

                    foreach (var group in groupsToRemove)
                    {
                        UserInfoProvider.RemoveUserFromRole(user.UserName,
                                                            RoleInfoProvider.GetRoles()
                                                            .OnSite(SiteContext.CurrentSiteID)
                                                            .Where("RoleDisplayName", QueryOperator.Equals, group)
                                                            .FirstOrDefault()?.RoleName ?? "", SiteContext.CurrentSiteName);
                    }
                }

                AuthenticationHelper.AuthenticateUser(user.UserName, false);
                MembershipActivityLogger.LogLogin(user.UserName, DocumentContext.CurrentDocument);

                var returnUrl = ValidationHelper.GetString(context.Request.Params["state"], string.Empty);
                URLHelper.Redirect(URLHelper.GetAbsoluteUrl(returnUrl));
            }
            catch (Exception exception)
            {
                EventLogProvider.LogException("AzureActiveDirectory", "Login", exception);
            }
        }
コード例 #21
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            /*
             * https://portal.azure.com/#blade/Microsoft_AAD_IAM/ApplicationBlade/objectId/8aa9350a-d919-4fb2-8eb2-5af69c2469e0/appId/3a2eaceb-1ff3-49a4-9156-dc7fd7b15409
             *
             */
            string authority = Configuration["AzureAd:AzureAdInstance"];// + Configuration["AzureAd:Domain"];

            services.AddApplicationInsightsTelemetry(Configuration);
            var str = Configuration.GetConnectionString("DefaultConnection");

            Trace.TraceError(str);
            Trace.Flush();

            services.Configure <AzureAdOptions>(Configuration.GetSection("AzureAD"));

            //str = "Server=tcp:nynftttf24v12.database.windows.net,1433;Initial Catalog=tkDemoLoadToSQLDB;Persist Security Info=False;User ID=tkadmin;Password=aA12weRT5$$L;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
            //DB
            services.AddDbContextPool <TenantContext>(
                options => options.UseSqlServer(str));


            var sp = services.BuildServiceProvider();
            var db = sp.GetService <TenantContext>();

            db.Database.EnsureCreated();


            services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme          = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            //.AddAzureAd(options => Configuration.Bind("AzureAd", options))
            .AddCookie()
            .AddOpenIdConnect(o =>
            {
                o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                o.ClientId     = Configuration["AzureAD:ClientId"];
                o.Authority    = authority;

                //Neccessary to get code!!!
                o.ClientSecret = Configuration["AzureAD:ClientSecret"];
                //o.SignedOutRedirectUri = Configuration["AzureAd:PostLogoutRedirectUri"];
                o.ResponseType = "code id_token";

                //token = "oauth2AllowImplicitFlow": true, and for JavaScript
                //"code id_token"

                o.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false
                };
                o.Events = new OpenIdConnectEvents
                {
                    OnRemoteSignOut = (context) =>
                    {
                        return(Task.FromResult(0));
                    },
                    OnRedirectToIdentityProvider = (context) =>
                    {
                        //string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + "/";
                        //context.ProtocolMessage.RedirectUri = appBaseUrl;
                        //context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                        return(Task.FromResult(0));
                    },
                    OnTokenValidated = async(context) =>
                    {
                        var tid = context.SecurityToken.Claims.FirstOrDefault(p => p.Type == "tid").Value.ToLower(); //Tenant
                        if (tid == "a757c7b8-69a2-4b92-b277-be767fc38487")
                        {
                            return;                                                //Own
                        }
                        var tenantdb = await db.Tenants.FirstOrDefaultAsync(p => p.TenantGuid == tid);
                        if (tenantdb == null)
                        {
                            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                            //context.Response.Redirect("/Home/Error");
                            context.HandleResponse();
                        }

                        return;
                    },
                    OnTokenResponseReceived = (context) =>
                    {
                        Debug.WriteLine(context);
                        return(Task.FromResult(0));
                    },
                    OnAuthorizationCodeReceived = async(context) =>
                    {
                        Debug.WriteLine(context.TokenEndpointRequest.Code);
                        try
                        {
                            var authContext = new AuthenticationContext($"{Configuration["AzureAD:AzureAdInstance"]}");
                            var creds       = new ClientCredential(Configuration["AzureAD:ClientId"], Configuration["AzureAD:ClientSecret"]);
                            string p        = $"{Configuration["AzureAD:Domain"] + "/signin-oidc"}";
                            var redirectUri = new Uri(p); //The same as during login!!!

                            //Because we have no Implicit Flow enabled!
                            var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                                context.TokenEndpointRequest.Code, redirectUri, creds,
                                "https://graph.microsoft.com/");

                            var gsc = new GraphServiceClient(
                                new DelegateAuthenticationProvider(
                                    (requestMessage) =>
                            {
                                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authResult.AccessToken);

                                return(Task.FromResult(0));
                            }));


                            //This can be done by any user (no admin consent)
                            var me = await gsc.Me.Request().GetAsync();

                            //Including Transitive, DirectoryObjects!
                            //var objects = await gsc.DirectoryObjects.GetByIds(me.ToList(), new string[] { "group", "directoryRole" }).Request().PostAsync();

                            //To read groups - we need admin consent
                            //Get group name require admin consent
                            var myGroup        = await gsc.Me.MemberOf.Request().GetAsync();
                            var claimsIdentity = (ClaimsIdentity)context.Principal.Identity;
                            foreach (var item in myGroup)
                            {
                                switch (item)
                                {
                                case Microsoft.Graph.Group group:
                                    claimsIdentity.AddClaim(new Claim("tkgroups", group.DisplayName));
                                    break;

                                case Microsoft.Graph.DirectoryRole role:
                                    claimsIdentity.AddClaim(new Claim("tkgroups", role.DisplayName));
                                    break;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.ToString());
                        }

                        //return Task.FromResult(0);
                    },
                    OnAuthenticationFailed = (context) =>
                    {
                        context.Response.Redirect("/Home/Error");
                        context.HandleResponse();
                        return(Task.FromResult(0));
                    }
                };
            });

            services.AddMvc();


            //Registration: https://portal.azure.com/#blade/Microsoft_AAD_IAM/ApplicationBlade/objectId/8aa9350a-d919-4fb2-8eb2-5af69c2469e0/appId/3a2eaceb-1ff3-49a4-9156-dc7fd7b15409
            //AppID: https://tkdxpl.onmicrosoft.com/TK2017MTAADv3
            //
            List <string> groupGuid = new List <string>();

            groupGuid.Add("8542e184-3375-49de-8401-131a73ed9d9c");
            ///tkopaczmse3             da2d4106-4bd5-4068-b2f1-8e47c7b8fe71, TKTEST1 - [email protected]
            ///tkdpepl.onmicrosoft.com a668c53a-0586-4abd-8732-13d6dc03c7ae, GROUP1 - [email protected]
            ///tkdxpl1.onmicrosoft.com f25fcc71-d538-4140-babf-32bfa7d599a1, tkdxpl1group [email protected]
            //Ugly, demo only - should be dynamics! After adding new tenant we need to restart app!
            try
            {
                foreach (var item in db.Tenants.Where(p => p.TenantGuid != ""))
                {
                    groupGuid.Add(item.GroupGuid);
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
            services.AddAuthorization(options =>
            {
                //In general - for single tenant, where we can control "names" of groups
                //OneCla
                options.AddPolicy("AdminPolicy", policy => policy.RequireClaim("tkgroups", new string[] { "Admin", "tkdxpl1group" }));
                options.AddPolicy("Admin1Policy", policy => policy.RequireClaim("tkgroups", "Admin1"));
                //Require groupMembershipClaims in manifest
                //Guid from: https://portal.azure.com/?r=1#blade/Microsoft_AAD_IAM/GroupDetailsMenuBlade/Properties/groupId/8542e184-3375-49de-8401-131a73ed9d9c
                options.AddPolicy("AdminPolicyByGuid", policy => policy.RequireClaim("groups", groupGuid));
            });
            //https://portal.office.com/account/#apps, App Permission, for user
            //https://portal.office.com/myapps <-admin
            //https://portal.azure.com/#blade/Microsoft_AAD_IAM/EnterpriseApplicationListBlade <- admin, enterprise apps (after sign up)
            //As Admin:
            //https://manage.windowsazure.com/@tkopaczmsE3.onmicrosoft.com#Workspaces/ActiveDirectoryExtension/Directory/a07319e7-7cb1-41fe-9ebf-250e5deba957/apps
        }
コード例 #22
0
        public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
        {
            loggerfactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Information);

            // Simple error page
            app.Use(async(context, next) =>
            {
                try
                {
                    await next();
                }
                catch (Exception ex)
                {
                    if (!context.Response.HasStarted)
                    {
                        context.Response.Clear();
                        context.Response.StatusCode = 500;
                        await context.Response.WriteAsync(ex.ToString());
                    }
                    else
                    {
                        throw;
                    }
                }
            });

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            var clientId     = Configuration["oidc:clientid"];
            var clientSecret = Configuration["oidc:clientsecret"];
            var authority    = Configuration["oidc:authority"];
            var resource     = "https://graph.windows.net";

            app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
            {
                ClientId     = clientId,
                ClientSecret = clientSecret, // for code flow
                Authority    = authority,
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                // GetClaimsFromUserInfoEndpoint = true,
                Events = new OpenIdConnectEvents()
                {
                    OnAuthorizationCodeReceived = async context =>
                    {
                        var request     = context.HttpContext.Request;
                        var currentUri  = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
                        var credential  = new ClientCredential(clientId, clientSecret);
                        var authContext = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForCodeRedemption(context.Properties));

                        var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                            context.ProtocolMessage.Code, new Uri(currentUri), credential, resource);

                        context.HandleCodeRedemption();
                    }
                }
            });

            app.Run(async context =>
            {
                if (context.Request.Path.Equals("/signout"))
                {
                    await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync($"<html><body>Signing out {context.User.Identity.Name}<br>{Environment.NewLine}");
                    await context.Response.WriteAsync("<a href=\"/\">Sign In</a>");
                    await context.Response.WriteAsync($"</body></html>");
                    return;
                }

                if (!context.User.Identities.Any(identity => identity.IsAuthenticated))
                {
                    await context.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties {
                        RedirectUri = "/"
                    });
                    return;
                }

                context.Response.ContentType = "text/html";
                await context.Response.WriteAsync($"<html><body>Hello Authenticated User {context.User.Identity.Name}<br>{Environment.NewLine}");
                await context.Response.WriteAsync("Claims:<br>" + Environment.NewLine);
                foreach (var claim in context.User.Claims)
                {
                    await context.Response.WriteAsync($"{claim.Type}: {claim.Value}<br>{Environment.NewLine}");
                }

                await context.Response.WriteAsync("Tokens:<br>" + Environment.NewLine);
                try
                {
                    // Use ADAL to get the right token
                    var authContext     = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForApiCalls(context, CookieAuthenticationDefaults.AuthenticationScheme));
                    var credential      = new ClientCredential(clientId, clientSecret);
                    string userObjectID = context.User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                    var result          = await authContext.AcquireTokenSilentAsync(resource, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));

                    await context.Response.WriteAsync($"access_token: {result.AccessToken}<br>{Environment.NewLine}");
                }
                catch (Exception ex)
                {
                    await context.Response.WriteAsync($"AquireToken error: {ex.Message}<br>{Environment.NewLine}");
                }

                await context.Response.WriteAsync("<a href=\"/signout\">Sign Out</a>");
                await context.Response.WriteAsync($"</body></html>");
            });
        }
コード例 #23
0
        /// <summary>
        /// Configure Auth
        /// </summary>
        /// <param name="app">App builder</param>
        /// <param name="container">DI container</param>
        public void ConfigureAuth(IAppBuilder app, Autofac.IContainer container)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            var validUpns = ConfigurationManager.AppSettings["ValidUpns"]
                            ?.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                            ?.Select(s => s.Trim())
                            ?? new string[0];

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions("AppLogin")
            {
                ClientId              = clientId,
                Authority             = authority,
                RedirectUri           = redirectUri,
                PostLogoutRedirectUri = postLogoutRedirectUri,
                Notifications         = new OpenIdConnectAuthenticationNotifications()
                {
                    SecurityTokenValidated = (context) =>
                    {
                        var upnClaim = context?.AuthenticationTicket?.Identity?.Claims?
                                       .FirstOrDefault(c => c.Type == ClaimTypes.Upn);
                        var upn = upnClaim?.Value;

                        if (upn == null ||
                            !validUpns.Contains(upn, StringComparer.OrdinalIgnoreCase))
                        {
                            context.OwinContext.Response.Redirect("/Account/InvalidUser?upn=" + upn);
                            context.HandleResponse();
                        }

                        return(Task.CompletedTask);
                    },
                    RedirectToIdentityProvider = (context) =>
                    {
                        if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                        {
                            context.ProtocolMessage.Prompt = OpenIdConnectPrompt.Login;
                        }

                        return(Task.CompletedTask);
                    },
                },
            });

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions(Constants.SharePointAppLoginAuthenticationType)
            {
                AuthenticationMode         = AuthenticationMode.Passive,
                ClientId                   = ConfigurationManager.AppSettings["GraphAppClientId"],
                ClientSecret               = ConfigurationManager.AppSettings["GraphAppClientSecret"],
                Authority                  = authority,
                RedirectUri                = redirectUri,
                PostLogoutRedirectUri      = postLogoutRedirectUri,
                SignInAsAuthenticationType = Constants.SharePointAppLoginAuthenticationType,
                Notifications              = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthorizationCodeReceived = async(context) =>
                    {
                        var authContext = new AuthenticationContext(context.Options.Authority);
                        var credential  = new ClientCredential(context.Options.ClientId, context.Options.ClientSecret);

                        var tokenResponse = await authContext.AcquireTokenByAuthorizationCodeAsync(context.Code, new Uri(redirectUri), credential, context.Options.ClientId);

                        var tokenHelper = container.Resolve <TokenHelper>();
                        var upn         = context.AuthenticationTicket.Identity.Name;
                        await tokenHelper.SetSharePointUserAsync(upn, tokenResponse.AccessToken);
                    },

                    RedirectToIdentityProvider = (context) =>
                    {
                        if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                        {
                            context.ProtocolMessage.Prompt = OpenIdConnectPrompt.Login;
                        }

                        return(Task.CompletedTask);
                    },
                },
            });
            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Upn;
        }
コード例 #24
0
        public static async Task <string> AuthorizationCodeReceived(IServiceProvider serviceProvider, IKeyValueSettings openIdSettings, ClaimsPrincipal principal, string code, string redirectUri, bool validateAuthority = false)
        {
            IContainerResolve container = serviceProvider.GetService(typeof(IContainerResolve)) as IContainerResolve;

            if (null == container)
            {
                throw new NullReferenceException("No container resolve is defined.");
            }


            container.TryResolve <ILogger>(out var logger);

            if (!container.TryResolve <ICacheKeyGenerator>(out var keyGen))
            {
                logger?.Technical().From(typeof(OpenIdConnectAuthenticationHandlers)).Error($"No Cache key generator is registered. Unable to uniquely identify a user.").Log();
                throw new NullReferenceException("ICacheKeyGenerator is not regeistered in the DI container.");
            }

            try
            {
                var userObjectId = keyGen.UserClaimIdentifier(principal.Identity as ClaimsIdentity);
                var authority    = openIdSettings.Values[TokenKeys.AuthorityKey];
                var resource     = openIdSettings.Values[TokenKeys.ServiceApplicationIdKey];

                logger?.Technical().From(typeof(OpenIdConnectAuthenticationHandlers))
                .System($"Get authenticationContext for authority: {authority}, resource: {resource}, user identifier: {userObjectId}.")
                .Add("Authority", authority)
                .Add("Resource", resource)
                .Add("UserID", userObjectId)
                .Log();

                var credential = new ClientCredential(openIdSettings.Values[TokenKeys.ClientIdKey], openIdSettings.Values[TokenKeys.ApplicationKey]);


                var authContext = new AuthenticationContext(authority, validateAuthority, new Cache(logger, container, resource + openIdSettings.Values[TokenKeys.AuthenticationTypeKey] + userObjectId));
                logger?.Technical().From(typeof(OpenIdConnectAuthenticationHandlers)).System($"Acquire a token based on the OpenID code received for redirectUri: {redirectUri}, credential.ClientId {credential.ClientId}, resource: {resource}.")
                .Add("RedirectUri", redirectUri)
                .Add("ClientId", credential.ClientId)
                .Add("Resource", resource)
                .Log();



                var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                    code,
                    new Uri(redirectUri, UriKind.RelativeOrAbsolute),
                    credential,
                    credential.ClientId);

                logger?.Technical().From(typeof(OpenIdConnectAuthenticationHandlers)).System($"Token is acquired and expired at {result.ExpiresOn}.").Log();
                if (null != result.UserInfo)
                {
                    logger?.Technical().From(typeof(OpenIdConnectAuthenticationHandlers)).System($"Token uniqueId = {result.UserInfo.UniqueId}").Log();
                    logger?.Technical().From(typeof(OpenIdConnectAuthenticationHandlers)).System($"Token displayableId = {result.UserInfo.DisplayableId}").Log();
                }
                else
                {
                    logger?.Technical().From(typeof(OpenIdConnectAuthenticationHandlers))
                    .Warning("No OpenId Token was received based on an code.")
                    .Add("Code", code)
                    .Log();
                }

                return(result.AccessToken);
            }
            catch (Exception ex)
            {
                logger?.Technical().From(typeof(OpenIdConnectAuthenticationHandlers)).Exception(ex).Log();
                throw;
            }
        }
コード例 #25
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            // Configure session middleware.
            app.UseSession();

            app.UseCookieAuthentication();

            app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions()
            {
                ClientId     = Configuration["Authentication:AzureAd:ClientId"],
                ClientSecret = Configuration["Authentication:AzureAd:ClientSecret"],
                Authority    = Configuration["Authentication:AzureAd:AADInstance"] + "common",
                CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"],
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                GetClaimsFromUserInfoEndpoint = false,

                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                },
                Events = new OpenIdConnectEvents
                {
                    OnTicketReceived = (context) =>
                    {
                        return(Task.FromResult(0));
                    },
                    OnAuthenticationFailed = (context) =>
                    {
                        context.Response.Redirect("/Home/Error");
                        context.HandleResponse(); // Suppress the exception
                        return(Task.FromResult(0));
                    },
                    OnAuthorizationCodeReceived = async(context) =>
                    {
                        // Exchange code for token using ADAL and save it into the token cache

                        // Either use tenant id with the token cache or clean the token cache each time user changes tenants or it will be confused
                        var tenantId    = (context.Ticket.Principal.FindFirst(AzureAdClaimTypes.TenantId))?.Value;
                        var clientCred  = new ClientCredential(context.Options.ClientId, context.Options.ClientSecret);
                        var authContext = new AuthenticationContext(context.Options.Authority.Replace("common", $"{tenantId}"), new NaiveSessionCache(tenantId, context.HttpContext.Session));
                        var authResult  = await authContext.AcquireTokenByAuthorizationCodeAsync(context.ProtocolMessage.Code, new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]), clientCred, "https://graph.microsoft.com");
                        context.HandleCodeRedemption(authResult.AccessToken, authResult.IdToken);
                    },
                    OnRedirectToIdentityProvider = (context) =>
                    {
                        string tenantId;
                        context.Properties.Items.TryGetValue("tenantId", out tenantId);
                        if (tenantId != null)
                        {
                            context.ProtocolMessage.IssuerAddress = context.ProtocolMessage.IssuerAddress.Replace("common", tenantId);
                        }
                        // Overwrite the common if specified
                        return(Task.FromResult(0));
                    },
                    OnTokenValidated = (context) =>
                    {
                        string tenantId;
                        context.Properties.Items.TryGetValue("tenantId", out tenantId);
                        if (tenantId != null)
                        {
                            string userTenantId = context.Ticket.Principal.FindFirst(AzureAdClaimTypes.TenantId)?.Value;
                            if (userTenantId != tenantId)
                            {
                                throw new Exception($"You signed in with wrong tenant, expected: {tenantId} but got {userTenantId}");
                            }
                        }
                        // You would validate whether the organization exists in the system etc.
                        return(Task.FromResult(0));
                    }
                }
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
コード例 #26
0
        public void ConfigureAuth(IAppBuilder app)
        {
            string ClientId  = ConfigurationManager.AppSettings["ClientID"];
            string Authority = string.Format(ConfigurationManager.AppSettings["Authority"], ConfigurationManager.AppSettings["AADId"]);
            string AzureResourceManagerIdentifier = ConfigurationManager.AppSettings["AzureResourceManagerIdentifier"];

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions {
            });
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                ClientId      = ClientId,
                Authority     = Authority,
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = (context) =>
                    {
                        // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                        // this allows you to deploy your app (to Azure Web Sites, for example) without having to change settings
                        // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                        //string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;

                        object obj = null;
                        if (context.OwinContext.Environment.TryGetValue("DomainHint", out obj))
                        {
                            string domainHint = obj as string;
                            if (domainHint != null)
                            {
                                context.ProtocolMessage.SetParameter("domain_hint", domainHint);
                            }
                        }

                        context.ProtocolMessage.RedirectUri           = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path);
                        context.ProtocolMessage.PostLogoutRedirectUri = new UrlHelper(HttpContext.Current.Request.RequestContext).Action
                                                                            ("Index", "Home", null, HttpContext.Current.Request.Url.Scheme);
                        context.ProtocolMessage.Resource = AzureResourceManagerIdentifier;
                        return(Task.FromResult(0));
                    },
                    AuthorizationCodeReceived = (context) =>
                    {
                        //X509Certificate2 keyCredential = new X509Certificate2(HttpContext.Current.Server.MapPath
                        //    (ConfigurationManager.AppSettings["KeyCredentialPath"]), "", X509KeyStorageFlags.MachineKeySet);
                        //ClientAssertionCertificate clientAssertion = new ClientAssertionCertificate(ClientId, keyCredential);

                        string signedInUserUniqueName = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value
                                                        .Split('#')[context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value.Split('#').Length - 1];

                        var tokenCache = new ADALTokenCache(signedInUserUniqueName);
                        tokenCache.Clear();

                        AuthenticationContext authContext = new AuthenticationContext(Authority, tokenCache);
                        ClientCredential credentials      = new ClientCredential(ConfigurationManager.AppSettings["ClientID"],
                                                                                 ConfigurationManager.AppSettings["ClientSecret"]);
                        AuthenticationResult result = authContext.AcquireTokenByAuthorizationCodeAsync(
                            context.Code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credentials).Result;

                        return(Task.FromResult(0));
                    }
                }
            });
        }
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions {
            });

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                ClientId                  = ClientId,
                Authority                 = this.authority,
                RedirectUri               = RedirectUri,
                PostLogoutRedirectUri     = RedirectUri,
                TokenValidationParameters = this.BuildTokenValidationParameters(),
                Notifications             = new OpenIdConnectAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = (context) =>
                    {
                        // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                        // this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
                        // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                        string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + "/";
                        context.ProtocolMessage.RedirectUri           = appBaseUrl;
                        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                        return(Task.FromResult(0));
                    },
                    SecurityTokenValidated = (context) =>
                    {
                        // retrieve caller data from the incoming principal
                        string issuer   = context.AuthenticationTicket.Identity.FindFirst("iss").Value;
                        string Upn      = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
                        string tenantId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;

                        if (
                            // the caller comes from an admin-consented, recorded issuer
                            (this.db.Tenants.FirstOrDefault(a => ((a.IssValue == issuer) && (a.AdminConsented))) == null)
                            // the caller is recorded in the db of users who went through the individual on-boarding
                            && (this.db.Users.FirstOrDefault(b => ((b.UPN == Upn) && (b.TenantID == tenantId))) == null)
                            )
                        {
                            // the caller was neither from a trusted issuer or a registered user - throw to block the authentication flow
                            throw new UnauthorizedAccessException("Please use the Sign-up link to sign -up for the ToDo list application.");
                        }

                        return(Task.FromResult(0));
                    },
                    AuthorizationCodeReceived = (context) =>
                    {
                        var code = context.Code;
                        ClientCredential credential = new ClientCredential(ClientId, AppKey);
                        string tenantId             = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                        string signedInUserId       = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;

                        AuthenticationContext authContext = new AuthenticationContext(AadInstance + tenantId, new ADALTokenCache(signedInUserId));

                        // The following operation fetches a token for Microsoft graph and caches it in the token cache
                        AuthenticationResult result = authContext.AcquireTokenByAuthorizationCodeAsync(
                            code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, GraphResourceId).Result;

                        return(Task.FromResult(0));
                    },
                    AuthenticationFailed = (context) =>
                    {
                        context.Response.Redirect("/Error/ShowError?signIn=true&errorMessage=" + context.Exception.Message);
                        context.HandleResponse();     // Suppress the exception
                        return(Task.FromResult(0));
                    }
                }
            });
        }
コード例 #28
0
        /// <summary>
        /// Configures the services.
        /// </summary>
        /// <param name="services">The services.</param>
        /// <remarks>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </remarks>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext <Briteplan>(options => options.UseSqlServer(Configuration["Data:ConnectionStrings:BloggingDatabase"]));

            services.AddAuthorization(ConfigureAuthPolicies());

            services.AddSingleton <IAuthorizationHandler, CheckUserRoleHandler>();

            services.AddAuthentication(auth =>
            {
                auth.DefaultScheme             = JwtBearerDefaults.AuthenticationScheme;
                auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                auth.DefaultChallengeScheme    = OpenIdConnectDefaults.AuthenticationScheme;
                auth.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddBpJwtBearer(options => Configuration.Bind("TokenOptions", options))
            .AddCookie().AddOpenIdConnect(opts =>
            {
                Configuration.GetSection("Authentication").Bind(opts);

                opts.Events = new OpenIdConnectEvents
                {
                    OnAuthorizationCodeReceived = async ctx =>
                    {
                        var request    = ctx.HttpContext.Request;
                        var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
                        var credential = new ClientCredential(ctx.Options.ClientId, ctx.Options.ClientSecret);

                        var distributedCache = ctx.HttpContext.RequestServices.GetRequiredService <IDistributedCache>();
                        var userId           = ctx.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

                        var cache = new AdalDistributedTokenCache(distributedCache, userId);

                        var authContext = new AuthenticationContext(ctx.Options.Authority, cache);

                        var result = await authContext.AcquireTokenByAuthorizationCodeAsync(ctx.ProtocolMessage.Code,
                                                                                            new Uri(currentUri),
                                                                                            credential,
                                                                                            ctx.Options.Resource);

                        var requiredService = ctx.HttpContext.RequestServices.GetRequiredService <IResourceManager>();
                        var resource        = await requiredService.GetByUsername(result.UserInfo.DisplayableId);
                        if (resource != null)
                        {
                            var claims = new List <Claim>
                            {
                                new Claim(YstervarkClaimNames.ResourceName, resource.ResourceName),
                                new Claim(YstervarkClaimNames.ResourceId, resource.ResourceId.ToString()),
                                new Claim(YstervarkClaimNames.TenantId, resource.TenantId.ToString()),
                                new Claim(JwtRegisteredClaimNames.Email, resource.Emailaddress),
                            };
                            claims.AddRange(resource.ResourceRole.Select(roleModel =>
                                                                         new Claim(ClaimsIdentity.DefaultRoleClaimType, roleModel.Role.RoleName)));
                            ctx.Principal.AddIdentity(new ClaimsIdentity(claims));
                        }
                        else
                        {
                            ctx.Fail(new UnauthorizedAccessException());
                            return;
                        }

                        ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
                    }
                };
            });

            services.AddMvc().AddJsonOptions(j =>
            {
                j.SerializerSettings.ContractResolver  = new DefaultContractResolver();
                j.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1",
                             new Info
                {
                    Title   = "Ystervark",
                    Version = "v1",
                    Contact = new Contact
                    {
                        Email = "*****@*****.**",
                        Name  = "Richard Bailey",
                        Url   = "https://github.com/Programm3r"
                    }
                });
            });

            services.AddSignalR();
        }
コード例 #29
0
        /// <summary>
        /// Configures application authentication.
        /// </summary>
        /// <param name="app">The application to configure.</param>
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions {
            });

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                ClientId  = ApplicationConfiguration.ActiveDirectoryClientID,
                Authority = ApplicationConfiguration.ActiveDirectoryEndPoint + "common",
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    // instead of using the default validation (validating against a single issuer value, as we do in line of business apps),
                    // we inject our own multitenant validation logic
                    ValidateIssuer = false,
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = (context) =>
                    {
                        context.ProtocolMessage.Parameters.Add("lc", Resources.Culture.LCID.ToString());
                        return(Task.FromResult(0));
                    },
                    AuthorizationCodeReceived = async(context) =>
                    {
                        string userTenantId         = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                        string signedInUserObjectId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

                        // login to the user AD tenant
                        ClientCredential webPortalcredentials = new ClientCredential(ApplicationConfiguration.ActiveDirectoryClientID, ApplicationConfiguration.ActiveDirectoryClientSecret);
                        AuthenticationContext userAuthContext = new AuthenticationContext(ApplicationConfiguration.ActiveDirectoryEndPoint + userTenantId);
                        AuthenticationResult userAuthResult   = userAuthContext.AcquireTokenByAuthorizationCodeAsync(
                            context.Code,
                            new Uri(
                                HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)),
                            webPortalcredentials,
                            ApplicationConfiguration.ActiveDirectoryGraphEndPoint).Result;

                        // acquire a graph token to manage the user tenant
                        Uri serviceRoot = new Uri(new Uri(ApplicationConfiguration.ActiveDirectoryGraphEndPoint), userTenantId);
                        ActiveDirectoryClient userAdClient = new ActiveDirectoryClient(serviceRoot, async() => await Task.FromResult(userAuthResult.AccessToken));

                        // add the user roles to the claims
                        var userMemberships = userAdClient.Users.GetByObjectId(signedInUserObjectId).MemberOf.ExecuteAsync().Result;

                        foreach (var membership in userMemberships.CurrentPage)
                        {
                            DirectoryRole role = membership as DirectoryRole;

                            if (role != null)
                            {
                                context.AuthenticationTicket.Identity.AddClaim(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Role, role.DisplayName));
                            }
                        }

                        if (userTenantId != ApplicationConfiguration.ActiveDirectoryTenantId)
                        {
                            string partnerCenterCustomerId = string.Empty;

                            // Check to see if this login came from the tenant of a customer of the partner
                            var customerDetails = await ApplicationDomain.Instance.PartnerCenterClient.Customers.ById(userTenantId).GetAsync();

                            // indeed a customer
                            partnerCenterCustomerId = customerDetails.Id;

                            if (!string.IsNullOrWhiteSpace(partnerCenterCustomerId))
                            {
                                // add the customer ID to the claims
                                context.AuthenticationTicket.Identity.AddClaim(new System.Security.Claims.Claim("PartnerCenterCustomerID", partnerCenterCustomerId));

                                // fire off call to retrieve this customer's subscriptions and populate the CustomerSubscriptions Repository.
                            }
                        }
                        else
                        {
                            if (context.AuthenticationTicket.Identity.FindFirst(System.Security.Claims.ClaimTypes.Role).Value != Startup.GlobalAdminUserRole)
                            {
                                // this login came from the partner's tenant, only allow admins to access the site, non admins will only
                                // see the unauthenticated experience but they can't configure the portal nor can purchase
                                Trace.TraceInformation("Blocked log in from non admin partner user: {0}", signedInUserObjectId);

                                throw new AuthorizationException(System.Net.HttpStatusCode.Unauthorized, Resources.NonAdminUnauthorizedMessage);
                            }
                        }
                    },
                    AuthenticationFailed = (context) =>
                    {
                        // redirect to the error page
                        string errorMessage = (context.Exception.InnerException == null) ?
                                              context.Exception.Message : context.Exception.InnerException.Message;
                        context.OwinContext.Response.Redirect($"/Home/Error?errorMessage={errorMessage}");

                        context.HandleResponse();
                        return(Task.FromResult(0));
                    }
                }
            });
        }
コード例 #30
0
        public void ConfigureAuth(IAppBuilder app)
        {
            Certificate = LoadCertificate();

            if (Certificate == null)
            {
                throw new Exception("Certificate == null");
            }

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                ClientId  = clientId,
                Authority = Authority,

                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidateIssuer = false
                },

                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    //
                    // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                    //
                    AuthorizationCodeReceived = async(context) =>
                    {
                        //  This code gets the AccessToken for the AAD graph. This will be needed for some scenarios. However, it might
                        //  be that we should ask for the services resource id at this stage. The AuthenticationResult includes a RefreshToken.

                        var code = context.Code;

                        string userObjectID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                        string tenantId     = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;

                        string authority = string.Format(aadInstance, tenantId);

                        AuthenticationContext authContext = new AuthenticationContext(authority, new NaiveSessionCache(userObjectID));
                        ClientAssertionCertificate clientAssertionCertificate = new ClientAssertionCertificate(clientId, Certificate);
                        AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), clientAssertionCertificate, graphResourceId);
                    },
                    RedirectToIdentityProvider = (context) =>
                    {
                        // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                        // this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
                        // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                        string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                        context.ProtocolMessage.RedirectUri           = appBaseUrl + "/";
                        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                        return(Task.FromResult(0));
                    },
                    SecurityTokenReceived = (context) =>
                    {
                        return(Task.FromResult(0));
                    },
                    AuthenticationFailed = (context) =>
                    {
                        //context.OwinContext.Response.Redirect("/Home/Error");
                        //context.HandleResponse(); // Suppress the exception
                        return(Task.FromResult(0));
                    }
                }
            });
        }
コード例 #31
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.AddAuthentication(options =>
            {
                options.DefaultScheme          = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
            {
                Configuration.Bind("OpenId", options);

                // We need the authorization code to get both id and access tokens
                options.ResponseType = "code id_token";

                // Saves the access token in the cookies
                options.SaveTokens = true;

                // Session lifetime will match the tokens'
                options.UseTokenLifetime = true;

                // WorkflowGen's GraphQL API doesn't have a /userinfo endpoint
                // like described in the OpenID Connect protocol. This prevents
                // the middleware from requesting from this endpoint.
                options.GetClaimsFromUserInfoEndpoint = false;
                options.TokenValidationParameters     = new TokenValidationParameters
                {
                    NameClaimType = "name",
                    RoleClaimType = "role"
                };

                // Adds an action to map custom claims from additional scopes.
                options.ClaimActions.MapUniqueJsonKey("sub", "sub");
                options.ClaimActions.MapUniqueJsonKey("name", "name");
                options.ClaimActions.MapUniqueJsonKey("given_name", "given_name");
                options.ClaimActions.MapUniqueJsonKey("family_name", "family_name");
                options.ClaimActions.MapUniqueJsonKey("profile", "profile");
                options.ClaimActions.MapUniqueJsonKey("email", "email");

                // Ensures that only the following scopes are requested.
                // If you need more, add them here.
                options.Scope.Clear();
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("email");

                options.Events = new OpenIdConnectEvents
                {
                    // Manually handles the exchange of the authorization code
                    // for tokens (id token and access token)
                    OnAuthorizationCodeReceived = async context =>
                    {
                        var request    = context.HttpContext.Request;
                        var currentUri = UriHelper.BuildAbsolute(
                            scheme: request.Scheme,
                            host: request.Host,
                            pathBase: request.PathBase,
                            path: request.Path
                            );
                        var credential  = new ClientCredential(options.ClientId, options.ClientSecret);
                        var authContext = new AuthenticationContext(
                            options.Authority,
                            tokenCache: AuthPropertiesTokenCache.ForCodeRedemption(context.Properties)
                            );
                        var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                            authorizationCode: context.ProtocolMessage.Code,
                            redirectUri: new Uri(currentUri),
                            credential,
                            resource: options.Resource
                            );

                        context.HandleCodeRedemption(result.AccessToken, result.IdToken);
                    }
                };
            });
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddTransient <IGraphQLClient, GraphQLHttpClient>(provider =>
            {
                // Retrieve the access token from the TokenCache.
                var httpContextAccessor = provider.GetService <IHttpContextAccessor>();
                var client = new GraphQLHttpClient(Configuration["OpenId:Resource"]);
                (var _, var accessToken) = Utilities.GetTokensFromContext(
                    context: httpContextAccessor.HttpContext,
                    authority: Configuration["OpenId:Authority"],
                    clientId: Configuration["OpenId:ClientId"],
                    clientSecret: Configuration["OpenId:ClientSecret"],
                    resource: Configuration["OpenId:Resource"]
                    ).Result;

                client.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken}");
                return(client);
            });
            services.AddMvc(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }
コード例 #32
0
        public async Task <ActionResult> Files(string code)
        {
            AuthenticationContext authContext = new AuthenticationContext(
                ConfigurationManager.AppSettings["ida:AuthorizationUri"] + "/common",
                true);

            ClientCredential creds = new ClientCredential(
                ConfigurationManager.AppSettings["ida:ClientID"],
                ConfigurationManager.AppSettings["ida:Password"]);

            //Get the discovery information that was saved earlier
            CapabilityDiscoveryResult cdr = Helpers.GetFromCache("FilesDiscoveryResult") as CapabilityDiscoveryResult;

            //Get a client, if this page was already visited
            SharePointClient sharepointClient = Helpers.GetFromCache("SharePointClient") as SharePointClient;

            //Get an authorization code, if needed
            if (sharepointClient == null && cdr != null && code == null)
            {
                Uri redirectUri = authContext.GetAuthorizationRequestURL(
                    cdr.ServiceResourceId,
                    creds.ClientId,
                    new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                    UserIdentifier.AnyUser,
                    string.Empty);

                return(Redirect(redirectUri.ToString()));
            }

            //Create the SharePointClient
            if (sharepointClient == null && cdr != null && code != null)
            {
                sharepointClient = new SharePointClient(cdr.ServiceEndpointUri, async() =>
                {
                    var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                        code,
                        new Uri(Request.Url.AbsoluteUri.Split('?')[0]),
                        creds);

                    return(authResult.AccessToken);
                });

                Helpers.SaveInCache("SharePointClient", sharepointClient);
            }

            //Get the files
            var filesResults = await sharepointClient.Files.ExecuteAsync();

            var fileList = new List <MyFile>();

            foreach (var file in filesResults.CurrentPage.Where(f => f.Name != "Shared with Everyone").OrderBy(e => e.Name))
            {
                fileList.Add(new MyFile
                {
                    Id   = file.Id,
                    Name = file.Name,
                    Url  = file.WebUrl
                });
            }

            //Save the files
            Helpers.SaveInCache("FileList", fileList);

            //Show the files
            return(View(fileList));
        }
コード例 #33
0
        public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
        {
            loggerfactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Information);

            // Simple error page
            app.Use(async(context, next) =>
            {
                try
                {
                    await next();
                }
                catch (Exception ex)
                {
                    if (!context.Response.HasStarted)
                    {
                        context.Response.Clear();
                        context.Response.StatusCode = 500;
                        await context.Response.WriteAsync(ex.ToString());
                    }
                    else
                    {
                        throw;
                    }
                }
            });

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            var clientId     = "0ec0a7da-117a-40b3-b4df-35d850d3690f";                  //Configuration["oidc:clientid"];
            var clientSecret = "SLy6EyGCo4izbq4NYaJrOqJNylRI/Kdy7WYk88dzt3Q=";          //Configuration["oidc:clientsecret"];
            var authority    = "https://login.windows.net/tkopaczmse3.onmicrosoft.com"; //Configuration["oidc:authority"];
            var resource     = "https://graph.windows.net";

            app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
            {
                ClientId              = clientId,
                ClientSecret          = clientSecret, // for code flow
                Authority             = authority,
                ResponseType          = OpenIdConnectResponseType.CodeIdToken,
                PostLogoutRedirectUri = "/signed-out",
                // GetClaimsFromUserInfoEndpoint = true,
                Events = new OpenIdConnectEvents()
                {
                    OnAuthorizationCodeReceived = async context =>
                    {
                        var request     = context.HttpContext.Request;
                        var currentUri  = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
                        var credential  = new ClientCredential(clientId, clientSecret);
                        var authContext = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForCodeRedemption(context.Properties));

                        var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                            context.ProtocolMessage.Code, new Uri(currentUri), credential, resource);

                        context.HandleCodeRedemption();
                    }
                }
            });

            app.Run(async context =>
            {
                if (context.Request.Path.Equals("/signin"))
                {
                    if (context.User.Identities.Any(identity => identity.IsAuthenticated))
                    {
                        // User has already signed in
                        context.Response.Redirect("/");
                        return;
                    }

                    await context.Authentication.ChallengeAsync(
                        OpenIdConnectDefaults.AuthenticationScheme,
                        new AuthenticationProperties {
                        RedirectUri = "/"
                    });
                }
                else if (context.Request.Path.Equals("/signout"))
                {
                    await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                    await WriteHtmlAsync(context.Response,
                                         async response =>
                    {
                        await response.WriteAsync($"<h1>Signed out locally: {HtmlEncode(context.User.Identity.Name)}</h1>");
                        await response.WriteAsync("<a class=\"btn btn-primary\" href=\"/\">Sign In</a>");
                    });
                }
                else if (context.Request.Path.Equals("/signout-remote"))
                {
                    await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                    await context.Authentication.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
                }
                else if (context.Request.Path.Equals("/signed-out"))
                {
                    await WriteHtmlAsync(context.Response,
                                         async response =>
                    {
                        await response.WriteAsync($"<h1>You have been signed out.</h1>");
                        await response.WriteAsync("<a class=\"btn btn-primary\" href=\"/signin\">Sign In</a>");
                    });
                }
                else if (context.Request.Path.Equals("/remote-signedout"))
                {
                    await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                    await WriteHtmlAsync(context.Response,
                                         async response =>
                    {
                        await response.WriteAsync($"<h1>Signed out remotely: {HtmlEncode(context.User.Identity.Name)}</h1>");
                        await response.WriteAsync("<a class=\"btn btn-primary\" href=\"/\">Sign In</a>");
                    });
                }
                else
                {
                    if (!context.User.Identities.Any(identity => identity.IsAuthenticated))
                    {
                        await context.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties {
                            RedirectUri = "/"
                        });
                        return;
                    }

                    await WriteHtmlAsync(context.Response, async response =>
                    {
                        await response.WriteAsync($"<h1>Hello Authenticated User {HtmlEncode(context.User.Identity.Name)}</h1>");
                        await response.WriteAsync("<a class=\"btn btn-default\" href=\"/signout\">Sign Out Locally</a>");
                        await response.WriteAsync("<a class=\"btn btn-default\" href=\"/signout-remote\">Sign Out Remotely</a>");

                        await response.WriteAsync("<h2>Claims:</h2>");
                        await WriteTableHeader(response, new string[] { "Claim Type", "Value" }, context.User.Claims.Select(c => new string[] { c.Type, c.Value }));

                        await response.WriteAsync("<h2>Tokens:</h2>");
                        try
                        {
                            // Use ADAL to get the right token
                            var authContext     = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForApiCalls(context, CookieAuthenticationDefaults.AuthenticationScheme));
                            var credential      = new ClientCredential(clientId, clientSecret);
                            string userObjectID = context.User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                            var result          = await authContext.AcquireTokenSilentAsync(resource, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));

                            await response.WriteAsync($"<h3>access_token</h3><code>{HtmlEncode(result.AccessToken)}</code><br>");
                        }
                        catch (Exception ex)
                        {
                            await response.WriteAsync($"AquireToken error: {ex.Message}");
                        }
                    });
                }
            });
        }