Esempio n. 1
0
        /// <summary>
        /// Emits the current session tokens with an updated expiration time
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="context">The http context.</param>
        /// <param name="session">The current session record.</param>
        protected virtual async Task RefreshSessionTokensAsync(IHttpContext context, SessionRecord session)
        {
            if (session == null)
            {
                throw new ArgumentNullException(nameof(session));
            }

            // Renew if the token is starting to get old
            if ((session.Expires - DateTime.Now).TotalSeconds < ShortTermRefreshThreshold)
            {
                // If the connection is using SSL, require SSL for the cookie
                var usingssl = context.Request.SslProtocol != System.Security.Authentication.SslProtocols.None;

                session.Expires = DateTime.Now.AddSeconds(ShortTermExpirationSeconds);
                await ShortTermStorage.UpdateSessionExpirationAsync(session);

                if (!string.IsNullOrWhiteSpace(session.XSRFToken))
                {
                    context.Response.AddCookie(XSRFCookieName, session.XSRFToken, expires: session.Expires, httponly: false, path: CookiePath, secure: usingssl);
                }

                if (!string.IsNullOrWhiteSpace(session.Cookie))
                {
                    context.Response.AddCookie(AuthSessionCookieName, session.Cookie, expires: session.Expires, httponly: true, path: CookiePath, secure: usingssl);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Handles the request
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="context">The requests context.</param>
        public async Task <bool> HandleAsync(IHttpContext context)
        {
            var xsrf   = context.Request.Headers[XSRFHeaderName] ?? context.Request.Cookies[XSRFCookieName];
            var cookie = context.Request.Cookies[AuthSessionCookieName];

            SessionRecord session = null;

            if (!string.IsNullOrWhiteSpace(xsrf))
            {
                session = await ShortTermStorage.GetSessionFromXSRFAsync(xsrf);

                if (Utility.IsNullOrExpired(session))
                {
                    session = null;
                }
                else
                {
                    await RefreshSessionTokensAsync(context, session);
                }
            }

            if (session == null && !string.IsNullOrWhiteSpace(cookie))
            {
                session = await ShortTermStorage.GetSessionFromCookieAsync(cookie);

                if (Utility.IsNullOrExpired(session))
                {
                    session = null;
                }
                else
                {
                    await RefreshSessionTokensAsync(context, session);
                }
            }

            // Check that we have not already set the XSRF cookie
            if (context.Response.Cookies.FirstOrDefault(x => x.Name == XSRFCookieName) == null)
            {
                if (session == null)
                {
                    session = new SessionRecord()
                    {
                        XSRFToken = PRNG.GetRandomString(32),
                        Expires   = DateTime.Now.AddSeconds(ShortTermExpirationSeconds)
                    };
                    await ShortTermStorage.AddSessionAsync(session);
                }

                // If the connection is using SSL, require SSL for the cookie
                var usingssl = context.Request.SslProtocol != System.Security.Authentication.SslProtocols.None;

                context.Response.AddCookie(XSRFCookieName, session.XSRFToken, expires: session.Expires, httponly: false, secure: usingssl);
            }

            return(false);
        }
Esempio n. 3
0
        /// <summary>
        /// Handles the request
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="context">The requests context.</param>
        public async Task <bool> HandleAsync(IHttpContext context)
        {
            var xsrf = context.Request.Headers[XSRFHeaderName];

            if (string.IsNullOrWhiteSpace(xsrf))
            {
                return(SetXSRFError(context));
            }

            var session = await ShortTermStorage.GetSessionFromXSRFAsync(xsrf);

            if (Utility.IsNullOrExpired(session))
            {
                return(SetXSRFError(context));
            }

            await RefreshSessionTokensAsync(context, session);

            return(false);
        }
Esempio n. 4
0
        /// <summary>
        /// Handles the request
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="context">The requests context.</param>
        public async Task <bool> HandleAsync(IHttpContext context)
        {
            var xsrf        = context.Request.Headers[XSRFHeaderName] ?? context.Request.Cookies[XSRFCookieName];
            var cookie      = context.Request.Cookies[AuthSessionCookieName];
            var longterm    = context.Request.Cookies[AuthCookieName];
            var droppedxsrf = false;

            if (!string.IsNullOrWhiteSpace(xsrf))
            {
                var session = await ShortTermStorage.GetSessionFromXSRFAsync(xsrf);

                if (session != null)
                {
                    await ShortTermStorage.DropSessionAsync(session);

                    droppedxsrf = true;
                }

                context.Response.AddCookie(XSRFCookieName, "", path: CookiePath, expires: new DateTime(1970, 1, 1), maxage: 0);
            }

            if (!string.IsNullOrWhiteSpace(cookie))
            {
                var session = await ShortTermStorage.GetSessionFromCookieAsync(cookie);

                if (session != null)
                {
                    await ShortTermStorage.DropSessionAsync(session);
                }

                if (session != null || droppedxsrf)
                {
                    context.Response.AddCookie(AuthSessionCookieName, "", path: CookiePath, expires: new DateTime(1970, 1, 1), maxage: 0);
                }
            }

            if (!string.IsNullOrWhiteSpace(longterm))
            {
                if (LongTermStorage != null)
                {
                    var pbkdf2 = new LongTermCookie(longterm);
                    if (pbkdf2.IsValid)
                    {
                        var lts = await LongTermStorage.GetLongTermLoginAsync(pbkdf2.Series);

                        if (lts != null)
                        {
                            await LongTermStorage.DropLongTermLoginAsync(lts);
                        }
                    }
                }

                context.Response.AddCookie(AuthCookieName, "", path: CookiePath, expires: new DateTime(1970, 1, 1), maxage: 0);
            }

            context.Response.StatusCode    = (HttpStatusCode)ResultStatusCode;
            context.Response.StatusMessage = ResultStatusMessage;
            if (!string.IsNullOrWhiteSpace(RedirectUrl))
            {
                context.Response.Headers["Location"] = RedirectUrl;
            }

            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Handles the request
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="context">The requests context.</param>
        public virtual async Task <bool> HandleAsync(IHttpContext context)
        {
            if (!ForceCheck && !string.IsNullOrWhiteSpace(context.Request.UserID))
            {
                return(false);
            }

            var xsrf   = context.Request.Headers[XSRFHeaderName];
            var cookie = context.Request.Cookies[AuthSessionCookieName];

            if (UseXSRFTokens && CheckXSRFToken && string.IsNullOrWhiteSpace(xsrf))
            {
                return(SetXSRFError(context));
            }

            if (UseXSRFTokens && CheckXSRFToken)
            {
                var session = await ShortTermStorage.GetSessionFromXSRFAsync(xsrf);

                if (Utility.IsNullOrExpired(session))
                {
                    return(SetXSRFError(context));
                }

                if (string.IsNullOrWhiteSpace(cookie) || session.Cookie != cookie)
                {
                    if (await LoginWithBasicAuth(context))
                    {
                        return(false);
                    }

                    if (await PerformLongTermLogin(context))
                    {
                        return(false);
                    }

                    // Check for a Hijack response
                    if (context.Response.HasSentHeaders)
                    {
                        return(true);
                    }

                    return(SetLoginError(context));
                }

                await RefreshSessionTokensAsync(context, session);

                context.Request.UserID = session.UserID;
            }
            else
            {
                SessionRecord session = null;

                if (!string.IsNullOrWhiteSpace(cookie))
                {
                    session = await ShortTermStorage.GetSessionFromCookieAsync(cookie);
                }

                if (Utility.IsNullOrExpired(session))
                {
                    if (await LoginWithBasicAuth(context))
                    {
                        return(false);
                    }

                    if (await PerformLongTermLogin(context))
                    {
                        return(false);
                    }

                    // Check for a Hijack response
                    if (context.Response.HasSentHeaders)
                    {
                        return(true);
                    }

                    return(SetLoginError(context));
                }

                await RefreshSessionTokensAsync(context, session);

                context.Request.UserID = session.UserID;
            }

            return(false);
        }
Esempio n. 6
0
        /// <summary>
        /// Handles the request
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="context">The requests context.</param>
        public async Task <bool> HandleAsync(IHttpContext context)
        {
            var xsrf        = context.Request.Headers[XSRFHeaderName] ?? context.Request.Cookies[XSRFCookieName];
            var cookie      = context.Request.Cookies[AuthSessionCookieName];
            var longterm    = context.Request.Cookies[AuthCookieName];
            var droppedxsrf = false;

            if (!string.IsNullOrWhiteSpace(xsrf))
            {
                var session = await ShortTermStorage.GetSessionFromXSRFAsync(xsrf);

                if (session != null)
                {
                    // Kill the existing record
                    await ShortTermStorage.DropSessionAsync(session);

                    droppedxsrf = true;

                    // Register a new one on the same XSRF token,
                    // but without any user attached
                    await ShortTermStorage.AddSessionAsync(new SessionRecord()
                    {
                        UserID    = null,
                        Cookie    = null,
                        XSRFToken = session.XSRFToken,
                        Expires   = DateTime.Now.AddSeconds(ShortTermExpirationSeconds)
                    });
                }

                //context.Response.AddCookie(XSRFCookieName, "", path: CookiePath, expires: new DateTime(1970, 1, 1), maxage: 0);
            }

            if (!string.IsNullOrWhiteSpace(cookie))
            {
                var session = await ShortTermStorage.GetSessionFromCookieAsync(cookie);

                if (session != null)
                {
                    await ShortTermStorage.DropSessionAsync(session);
                }

                if (session != null || droppedxsrf)
                {
                    context.Response.AddCookie(AuthSessionCookieName, "", path: CookiePath, expires: new DateTime(1970, 1, 1), maxage: 0);
                }
            }

            if (!string.IsNullOrWhiteSpace(longterm))
            {
                if (LongTermStorage != null)
                {
                    var pbkdf2 = new LongTermCookie(longterm);
                    if (pbkdf2.IsValid)
                    {
                        var lts = await LongTermStorage.GetLongTermLoginAsync(pbkdf2.Series);

                        if (lts != null)
                        {
                            await LongTermStorage.DropLongTermLoginAsync(lts);
                        }
                    }
                }

                context.Response.AddCookie(AuthCookieName, "", path: CookiePath, expires: new DateTime(1970, 1, 1), maxage: 0);
            }

            context.Response.StatusCode    = (HttpStatusCode)ResultStatusCode;
            context.Response.StatusMessage = ResultStatusMessage;
            if (!string.IsNullOrWhiteSpace(RedirectUrl))
            {
                context.Response.Headers["Location"] = RedirectUrl;
            }

            return(true);
        }
Esempio n. 7
0
        /// <summary>
        /// Performs all steps required to do a login
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="context">The http context.</param>
        /// <param name="userid">The user ID.</param>
        /// <param name="series">The long-term series</param>
        /// <param name="withlongterm">A value indicating if a long-term session should be created</param>
        protected virtual async Task PerformLoginAsync(IHttpContext context, string userid, string series, bool withlongterm)
        {
            var session = new SessionRecord();

            // Re-use the XSRF if possible
            if (UseXSRFTokens)
            {
                var xsrf = context.Request.Headers[XSRFHeaderName];
                if (!string.IsNullOrWhiteSpace(xsrf))
                {
                    var prev = await ShortTermStorage.GetSessionFromXSRFAsync(xsrf);

                    if (!Utility.IsNullOrExpired(prev) && prev.UserID == userid && !string.IsNullOrWhiteSpace(userid))
                    {
                        session = prev;
                    }
                }
            }

            session.UserID  = userid;
            session.Expires = DateTime.Now.AddSeconds(ShortTermExpirationSeconds);

            // If the connection is using SSL, require SSL for the cookie
            var usingssl = context.Request.SslProtocol != System.Security.Authentication.SslProtocols.None;

            if (UseXSRFTokens)
            {
                session.XSRFToken = session.XSRFToken ?? PRNG.GetRandomString(32);
                context.Response.AddCookie(XSRFCookieName, session.XSRFToken, expires: session.Expires, httponly: false, path: CookiePath, secure: usingssl);
            }

            if (UseLongTermCookieStorage && LongTermStorage != null && (!string.IsNullOrWhiteSpace(series) || withlongterm))
            {
                var cookie = new LongTermCookie();
                if (!string.IsNullOrWhiteSpace(series))
                {
                    cookie.Series = series;
                }

                var st = new LongTermToken()
                {
                    UserID  = userid,
                    Expires = DateTime.Now.AddSeconds(LongTermDurationSeconds),
                    Series  = cookie.Series,
                    Token   = PBKDF2.CreatePBKDF2(cookie.Token)
                };

                await LongTermStorage.AddOrUpdateLongTermLoginAsync(st);

                context.Response.AddCookie(AuthCookieName, cookie.ToString(), expires: st.Expires, httponly: true, path: CookiePath, secure: usingssl);
            }

            session.Cookie = PRNG.GetRandomString(32);
            context.Response.AddCookie(AuthSessionCookieName, session.Cookie, expires: session.Expires, httponly: true, path: CookiePath, secure: usingssl);

            await ShortTermStorage.AddSessionAsync(session);

            SetLoginSuccess(context);

            context.Request.UserID = userid;
        }
Esempio n. 8
0
        /// <summary>
        /// Handles the request
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="context">The requests context.</param>
        public async Task <bool> HandleAsync(IHttpContext context)
        {
            if (context.Request.Method != "POST")
            {
                return(context.SetResponseMethodNotAllowed());
            }

            var xsrf = context.Request.Headers[XSRFHeaderName];

            if (RequireXSRFToken && string.IsNullOrWhiteSpace(xsrf))
            {
                return(SetXSRFError(context));
            }

            var username   = ExtractUsername(context);
            var password   = ExtractPassword(context);
            var rememberme = ExtractRememberMe(context);

            if (string.IsNullOrWhiteSpace(username))
            {
                return(SetLoginError(context));
            }

            if (string.IsNullOrWhiteSpace(password))
            {
                return(SetLoginError(context));
            }

            if (RequireXSRFToken)
            {
                var session = await ShortTermStorage.GetSessionFromXSRFAsync(xsrf);

                if (Utility.IsNullOrExpired(session))
                {
                    return(SetXSRFError(context));
                }
            }

            if (UseLongTermCookieStorage && LongTermStorage != null)
            {
                if (await PerformLongTermLogin(context))
                {
                    return(true);
                }

                // Check for a Hijack response
                if (context.Response.HasSentHeaders)
                {
                    return(true);
                }
            }

            var user =
                (await Authentication.GetLoginEntriesAsync(username))
                .FirstOrDefault(x => x != null && PBKDF2.ComparePassword(password, x.Token));

            if (user == null)
            {
                if (await LoginWithBasicAuth(context))
                {
                    return(true);
                }

                return(SetLoginError(context));
            }

            await PerformLoginAsync(context, user.UserID, null, rememberme);

            return(true);
        }
Esempio n. 9
0
        /// <summary>
        /// Performs all steps required to do a login
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="context">The http context.</param>
        /// <param name="userid">The user ID.</param>
        /// <param name="series">The long-term series</param>
        /// <param name="withlongterm">A value indicating if a long-term session should be created</param>
        protected virtual async Task PerformLoginAsync(IHttpContext context, string userid, string series, bool withlongterm)
        {
            var session = new SessionRecord();

            // Re-use the XSRF if possible
            if (UseXSRFTokens)
            {
                var xsrf = context.Request.Headers[XSRFHeaderName];
                if (!string.IsNullOrWhiteSpace(xsrf))
                {
                    var prev = await ShortTermStorage.GetSessionFromXSRFAsync(xsrf);

                    if (prev != null)
                    {
                        // Remove the previous entry to avoid conflicts
                        await ShortTermStorage.DropSessionAsync(prev);

                        // Re-use the XSRF token
                        session.XSRFToken = prev.XSRFToken;
                    }
                }
            }

            session.UserID  = userid;
            session.Expires = DateTime.Now.AddSeconds(ShortTermExpirationSeconds);

            // If the connection is using SSL, require SSL for the cookie
            var usingssl = context.Request.SslProtocol != System.Security.Authentication.SslProtocols.None;

            if (UseXSRFTokens)
            {
                session.XSRFToken = session.XSRFToken ?? PRNG.GetRandomString(32);
                context.Response.AddCookie(XSRFCookieName, session.XSRFToken, expires: session.Expires, httponly: false, path: CookiePath, secure: usingssl);
            }

            if (UseLongTermCookieStorage && LongTermStorage != null && (!string.IsNullOrWhiteSpace(series) || withlongterm))
            {
                var cookie = new LongTermCookie();
                if (!string.IsNullOrWhiteSpace(series))
                {
                    cookie.Series = series;
                }

                var st = new LongTermToken()
                {
                    UserID  = userid,
                    Expires = DateTime.Now.AddSeconds(LongTermDurationSeconds),
                    Series  = cookie.Series,
                    Token   = PBKDF2.CreatePBKDF2(cookie.Token)
                };

                await LongTermStorage.AddOrUpdateLongTermLoginAsync(st);

                context.Response.AddCookie(AuthCookieName, cookie.ToString(), expires: st.Expires, httponly: true, path: CookiePath, secure: usingssl);
            }

            session.Cookie = PRNG.GetRandomString(32);
            context.Response.AddCookie(AuthSessionCookieName, session.Cookie, expires: session.Expires, httponly: true, path: CookiePath, secure: usingssl);

            if (ShortTermStorage == null)
            {
                Console.WriteLine("Missing short term storage module, make sure you load Ceen.Security.Login.DatabaseStorageModule or manually set a storage module");
            }
            await ShortTermStorage.AddSessionAsync(session);

            SetLoginSuccess(context);

            context.Request.UserID = userid;
        }