コード例 #1
0
        public void Test_IdentifierNotInOpenIdCache()
        {
            SecuredAttribute  securedAttribute;
            HttpActionContext httpActionContext;
            HttpCookie        authCookie;
            HttpCookie        xsrfCookie;

            CookieHelper.CreateAuthenticationAndXsrfCookies(
                RequestContext.TenantId,
                WellKnownAliases.CurrentTenant.ReadiNowIdentityProviderInstance,
                Guid.NewGuid().ToString(),
                1234,
                true,                                                   // Persistent
                null,                                                   // Create new XSRF token,
                DateTime.Now,                                           // Issue date
                DateTime.Now.AddMinutes(10),                            // Expiry
                out authCookie,
                out xsrfCookie);

            httpActionContext = BuildHttpActionContext();
            httpActionContext.Request.Headers.Add(
                "Cookie",
                string.Format(
                    "{0}={1};{2}={3}",
                    authCookie.Name,
                    authCookie.Value,
                    xsrfCookie.Name,
                    xsrfCookie.Value));
            httpActionContext.Request.Headers.Add(
                LoginConstants.Headers.AngularJsXsrfToken,
                xsrfCookie.Value);
            httpActionContext.Request.RequestUri = new Uri(
                string.Format(
                    "http://a?{0}={1}",
                    LoginConstants.QueryString.XsrfToken,
                    xsrfCookie.Value),
                UriKind.Absolute);

            HttpContext.Current = BuildHttpContext();

            securedAttribute = new SecuredAttribute();
            Assert.That(() => securedAttribute.OnAuthorization(httpActionContext),
                        Throws.TypeOf <InvalidCredentialException>().And.Property("Message").EqualTo(UserAccountValidator.InvalidUserNameOrPasswordMessage));
        }
コード例 #2
0
        public void Test_CreateAuthenticationAndXsrfCookies(long tenantId, long identityProviderId, string identityProviderUserName, long userAccountId, string xsrfToken, bool persistent)
        {
            HttpCookie authCookie;
            HttpCookie xsrfCookie;
            FormsAuthenticationTicket ticket;
            AuthenticationToken       authTicket;

            HttpContext.Current = new HttpContext(new HttpRequest("", "http://tempuri.org", ""), new HttpResponse(new StringWriter()));

            CookieHelper.CreateAuthenticationAndXsrfCookies(tenantId, identityProviderId, identityProviderUserName, userAccountId, persistent, xsrfToken);

            authCookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName];
            Assert.That(authCookie, Is.Not.Null, "Null auth cookie");
            Assert.That(authCookie, Has.Property("Values").Count.EqualTo(1), "Incorrect auth cookie values");

            // ReSharper disable once PossibleNullReferenceException
            ticket = FormsAuthentication.Decrypt(authCookie.Value);
            Assert.That(ticket, Has.Property("Version").EqualTo(1));
            Assert.That(ticket, Has.Property("Name").EqualTo(LoginConstants.Cookie.CookieName));
            Assert.That(ticket, Has.Property("IssueDate").EqualTo(DateTime.Now).Within(TimeSpan.FromSeconds(10)));
            Assert.That(ticket, Has.Property("Expiration").EqualTo(DateTime.Now.AddMinutes(LoginConstants.Cookie.Timeout)).Within(TimeSpan.FromSeconds(10)));
            Assert.That(ticket, Has.Property("IsPersistent").EqualTo(persistent));

            // ReSharper disable once PossibleNullReferenceException
            authTicket = JSON.Deserialize <AuthenticationToken>(ticket.UserData);
            Assert.That(authTicket, Has.Property("TenantId").EqualTo(tenantId));
            Assert.That(authTicket, Has.Property("IdentityProviderId").EqualTo(identityProviderId));
            Assert.That(authTicket, Has.Property("IdentityProviderUserName").EqualTo(identityProviderUserName));
            Assert.That(authTicket, Has.Property("UserAccountId").EqualTo(userAccountId));
            Assert.That(authTicket, Has.Property("XsrfToken").EqualTo(xsrfToken));
            Assert.That(authTicket, Has.Property("Persist").EqualTo(persistent));

            xsrfCookie = HttpContext.Current.Response.Cookies[LoginConstants.Cookie.AngularDefaultXsrfCookieName];
            Assert.That(xsrfCookie, Is.Not.Null, "Null xsrf cookie");
            Assert.That(xsrfCookie, Has.Property("Values").Count.EqualTo(1), "Incorrect xsrf cookie values");
            Assert.That(xsrfCookie, Has.Property("Value").EqualTo(xsrfToken));
        }
コード例 #3
0
        public void Test_ExpiredAuthCookie()
        {
            SecuredAttribute  securedAttribute;
            HttpActionContext httpActionContext;
            HttpCookie        authCookie;
            HttpCookie        xsrfCookie;

            var requestContext = RequestContext.GetContext();

            CookieHelper.CreateAuthenticationAndXsrfCookies(
                RequestContext.TenantId,
                WellKnownAliases.CurrentTenant.ReadiNowIdentityProviderInstance,
                requestContext.Identity.Name,
                requestContext.Identity.Id,
                true,                                                   // Persistent
                null,                                                   // Create new XSRF token,
                DateTime.Now.AddMinutes(-10),                           // Issue date
                DateTime.Now.AddMinutes(-1),                            // Expiry
                out authCookie,
                out xsrfCookie);

            httpActionContext = BuildHttpActionContext();
            httpActionContext.Request.Headers.Add(
                "Cookie",
                string.Format(
                    "{0}={1};{2}={3}",
                    authCookie.Name,
                    authCookie.Value,
                    xsrfCookie.Name,
                    xsrfCookie.Value));
            HttpContext.Current = BuildHttpContext();

            securedAttribute = new SecuredAttribute();
            Assert.That(() => securedAttribute.OnAuthorization(httpActionContext),
                        Throws.TypeOf <AuthenticationTokenExpiredException>());
        }
コード例 #4
0
        public void Test_ExtendWindow(string requestPath, double offset, bool expectExtension)
        {
            SecuredAttribute  securedAttribute;
            HttpActionContext httpActionContext;
            HttpCookie        authCookie;
            HttpCookie        xsrfCookie;
            DateTime          issueDate;
            DateTime          expiryDate;

            // Ensure the ticket is over half way through its window
            issueDate  = DateTime.Now.AddMinutes(-(LoginConstants.Cookie.Timeout / 2) + offset);
            expiryDate = issueDate.AddMinutes(LoginConstants.Cookie.Timeout);

            var requestContext = RequestContext.GetContext();

            CookieHelper.CreateAuthenticationAndXsrfCookies(
                RequestContext.TenantId,
                WellKnownAliases.CurrentTenant.ReadiNowIdentityProviderInstance,
                requestContext.Identity.Name,
                requestContext.Identity.Id,
                true,                                                   // Persistent
                null,                                                   // Create new XSRF token,
                issueDate,
                expiryDate,
                out authCookie,
                out xsrfCookie);

            httpActionContext = BuildHttpActionContext();
            httpActionContext.Request.Headers.Add(
                "Cookie",
                string.Format(
                    "{0}={1};{2}={3}",
                    authCookie.Name,
                    authCookie.Value,
                    xsrfCookie.Name,
                    xsrfCookie.Value));
            httpActionContext.Request.Headers.Add(
                LoginConstants.Headers.AngularJsXsrfToken,
                xsrfCookie.Value);
            httpActionContext.Request.RequestUri = new Uri(
                string.Format(
                    "http://host{0}?{1}={2}",
                    requestPath,
                    LoginConstants.QueryString.XsrfToken,
                    xsrfCookie.Value),
                UriKind.Absolute);

            HttpContext.Current = BuildHttpContext();

            securedAttribute = new SecuredAttribute();
            securedAttribute.OnAuthorization(httpActionContext);

            if (expectExtension)
            {
                Assert.That(HttpContext.Current.Response.Cookies.AllKeys,
                            Is.EquivalentTo(new[]
                                            { FormsAuthentication.FormsCookieName, LoginConstants.Cookie.AngularDefaultXsrfCookieName }));
            }
            else
            {
                Assert.That(HttpContext.Current.Response.Cookies.AllKeys,
                            Is.Empty);
            }
        }
コード例 #5
0
        private static void AddFakeLoginTokens(HttpWebRequest request, string host, UserAccount userAccount)
        {
            var context = RequestContext.GetContext( );

            string userName;
            long   userId;

            if (userAccount == null)
            {
                userName = context.Identity.Name;
                userId   = context.Identity.Id;
            }
            else
            {
                userName = userAccount.Name;
                userId   = userAccount.Id;
            }

            string key = userName;
            long   readiNowIdentityProvider = WellKnownAliases.CurrentTenant.ReadiNowIdentityProviderInstance;

            Func <string, CookieInfo> getCookie = key1 =>
            {
                HttpCookie authCookie;
                HttpCookie xsrfCookie;

                CookieHelper.CreateAuthenticationAndXsrfCookies(
                    context.Tenant.Id,
                    readiNowIdentityProvider,
                    userName,
                    userId,
                    false,                                                  // Not persistent
                    null,                                                   // Create new XSRF token,
                    DateTime.Now,                                           // Issue date
                    DateTime.Now.AddMinutes(LoginConstants.Cookie.Timeout), // Expiry
                    out authCookie,
                    out xsrfCookie);

                Cookie authCookie2 = ToCookie(authCookie);
                Cookie xsrfCookie2 = ToCookie(xsrfCookie);

                var cookieInfo = new CookieInfo
                {
                    AuthCookie = authCookie2,
                    XsrfCookie = xsrfCookie2,
                    Expires    = authCookie2.Expires
                };
                return(cookieInfo);
            };

            // Get the cookieData
            if (key != null)
            {
                CookieInfo cookieData = Cookies.GetOrAdd(key, getCookie);
                if (cookieData.Expires < DateTime.Now.AddSeconds(10))
                {
                    // Refetch if expired
                    cookieData = Cookies.AddOrUpdate(key, getCookie, (key2, old) => getCookie(key2));
                }

                var uri = new Uri(host);
                request.CookieContainer = new CookieContainer( );
                request.CookieContainer.Add(uri, cookieData.AuthCookie);
                request.CookieContainer.Add(uri, cookieData.XsrfCookie);
                request.Headers.Add(LoginConstants.Headers.AngularJsXsrfToken, cookieData.XsrfCookie.Value);
            }
        }
コード例 #6
0
 public void Test_CreateAuthenticationAndXsrfCookies_InvalidUserId()
 {
     Assert.That(() => CookieHelper.CreateAuthenticationAndXsrfCookies(5, 5, "name", 0, true, "a"),
                 Throws.TypeOf <ArgumentOutOfRangeException>().And.Property("ParamName").EqualTo("userAccountId"));
 }
コード例 #7
0
 public void Test_CreateAuthenticationAndXsrfCookies_EmptyIdentityProviderUser()
 {
     Assert.That(() => CookieHelper.CreateAuthenticationAndXsrfCookies(5, 5, "", 0, true, "a"),
                 Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("identityProviderUser"));
 }
コード例 #8
0
        // ReSharper disable once InconsistentNaming
        public async Task <IHttpActionResult> OidcAuthResponseCallback(string tenant, string code = null, string state = null, string error = null, string error_description = null)
        {
            OpenIdConnectAuthorizationState authState = null;

            try
            {
                if (!string.IsNullOrWhiteSpace(error))
                {
                    return(BadRequest($"An error occurred during authorization. Error:{error}. Description:{error_description}"));
                }

                if (string.IsNullOrWhiteSpace(tenant))
                {
                    throw new WebArgumentNullException("tenant", "The tenant was not specified");
                }

                if (string.IsNullOrWhiteSpace(code))
                {
                    throw new WebArgumentNullException("code", "The code was not specified");
                }

                if (string.IsNullOrWhiteSpace(state))
                {
                    throw new WebArgumentNullException("state", "The state was not specified");
                }

                // For some reason ADFS is replacing the + signs (even the encoded ones) with spaces, so we undo it.
                // State is Base64 encoded so it should not contain spaces.
                if (!string.IsNullOrWhiteSpace(state))
                {
                    state = state.Replace(' ', '+');
                }

                var oidcLoginHandler = new OpenIdConnectLoginHandler(OpenIdConnectConfigurationManager);
                if (oidcLoginHandler.IsTokenValidationDisabled)
                {
                    EventLog.Application.WriteError("OpenIdConnectLoginHandler has token validation disabled. This is not be used in production.");
                    throw new AuthenticationException();
                }

                // Validate the state.
                authState = oidcLoginHandler.ValidateAuthState(state);

                using (var httpClient = new BasicHttpClient())
                {
                    // Process the authorization response.
                    var result = await oidcLoginHandler.ProcessOidcAuthorizationResponse(tenant, code, authState, new Uri(Request.RequestUri.GetLeftPart(UriPartial.Authority)), httpClient);

                    CookieHelper.CreateAuthenticationAndXsrfCookies(authState.TenantId, authState.IdentityProviderId, result.IdentityProviderUserName, result.RequestContextData.Identity.Id, true);
                }

                return(Redirect(authState.RedirectUrl));
            }
            catch (Exception exception)
            {
                var oidcConfigException = exception as OidcProviderInvalidConfigurationException;

                EventLog.Application.WriteError("Failed to process oidc authorization response. Error: {0}", exception.ToString());

                CookieHelper.DeleteAuthenticationAndXsrfCookies();
                if (!string.IsNullOrWhiteSpace(authState?.RedirectUrl))
                {
                    string delimiter = authState.RedirectUrl.Contains("?") ? "&" : "?";
                    string errorType = oidcConfigException != null ? "idpconfigerror" : "autherror";
                    return(Redirect(authState.RedirectUrl + delimiter + "error=" + errorType));
                }

                return(Unauthorized());
            }
        }
コード例 #9
0
        /// <summary>
        ///     Signs a software platform user into the system.
        /// </summary>
        /// <param name="jsonLoginCredential">The json login credential.</param>
        /// <returns></returns>
        private HttpResponseMessage <LoginResult> SigninSoftwarePlatform(JsonLoginCredential jsonLoginCredential)
        {
            var userAgent = Request?.Headers?.UserAgent?.ToString();

            try
            {
                using (new SecurityBypassContext( ))
                {
                    try
                    {
                        UserAccountValidator.Authenticate(jsonLoginCredential.Username, jsonLoginCredential.Password,
                                                          jsonLoginCredential.Tenant, true);
                    }
                    catch (ArgumentException ex)
                    {
                        throw new InvalidCredentialException("Invalid user name, password or tenant", ex);
                    }

                    RequestContext     context = ReadiNow.IO.RequestContext.GetContext( );
                    RequestContextData contextData;

                    UserAccount account = ReadiNow.Model.Entity.Get <UserAccount>(context.Identity.Id, true);

                    if (account != null)
                    {
                        /////
                        // If we are in integration test mode, update the test authorization info.
                        /////
                        if (TestAuthorization.IsEnabled)
                        {
                            TestAuthorization.Instance.SetTokenIdentifier(context.Tenant.Id, WellKnownAliases.CurrentTenant.ReadiNowIdentityProviderInstance, account.Name);
                        }

                        // Update cache
                        contextData = Factory.IdentityProviderRequestContextCache.GetRequestContextData(ReadiNow.IO.RequestContext.TenantId, WellKnownAliases.CurrentTenant.ReadiNowIdentityProviderInstance, jsonLoginCredential.Username, true);
                    }
                    else
                    {
                        throw new InvalidOperationException("No UserAccount found.");
                    }

                    ReadiNowIdentityProvider identityProvider = ReadiNow.Model.Entity.Get <ReadiNowIdentityProvider>(WellKnownAliases.CurrentTenant.ReadiNowIdentityProviderInstance);

                    if (!(identityProvider.IsProviderEnabled ?? true))
                    {
                        throw new AuthenticationException("The identity provider is not enabled.");
                    }

                    contextData.Identity.IdentityProviderTypeAlias = LoginConstants.ReadiNowIdentityProviderTypeAlias;

                    CookieHelper.CreateAuthenticationAndXsrfCookies(ReadiNow.IO.RequestContext.TenantId, WellKnownAliases.CurrentTenant.ReadiNowIdentityProviderInstance, jsonLoginCredential.Username, account.Id, jsonLoginCredential.Persistent);

                    AuditLogInstance.Get().OnLogon(true, jsonLoginCredential.Username, userAgent);

                    return(new HttpResponseMessage <LoginResult>(GetSuccessfulLoginResult(contextData, account.Id), HttpStatusCode.OK));
                }
            }
            catch (Exception exc)
            {
                if (ReadiNow.IO.RequestContext.IsSet)
                {
                    AuditLogInstance.Get().OnLogon(false, jsonLoginCredential.Username, userAgent);
                }

                EventLog.Application.WriteWarning("Software Platform login error. Username: {0}, Tenant: {1}. {2}", jsonLoginCredential.Username ?? "<null>", jsonLoginCredential.Tenant ?? "<null>", exc.Message);

                throw;  // rely on the ExceptionFilter to handle it.
            }
        }