zoukankan      html  css  js  c++  java
  • ASP.NET replay attack detection again 解决方案

    ASP.NET replay attack detection again

    Even ASP.NET Authentication says clearly that you have to have a secondary check to confirm if user is still an active logged in user (for example, we could block the user, user may have changed his password), Forms Authentication ticket does not offer any security against these things.

    UserSession has nothing to do with ASP.NET MVC Session, it is just a name here

    The solution I have implemented is,

    1. Create a UserSessions table in the database with UserSessionID (PK, Identity) UserID (FK) DateCreated, DateUpdated
    2. FormsAuthenticationTicket has a field called UserData, you can save UserSessionID in it.

    When User Logs in

    public void DoLogin(){
    
         // do not call this ...
         // FormsAuthentication.SetAuthCookie(....
    
         DateTime dateIssued = DateTime.UtcNow;
    
         var sessionID = db.CreateSession(UserID);
         var ticket = new FormsAuthenticationTicket(
                userName,
                dateIssued,
                dateIssued.Add(FormsAuthentication.Timeout),
                iSpersistent,
                // userData
                sessionID.ToString());
    
         HttpCookie cookie = new HttpCookie(
             FormsAuthentication.CookieName,
             FormsAuthentication.Encrypt(ticket));
         cookie.Expires = ticket.Expires;
         if(FormsAuthentication.CookieDomain!=null)
             cookie.Domain = FormsAuthentication.CookieDomain;
         cookie.Path = FormsAuthentication.CookiePath;
         Response.Cookies.Add(cookie);
    
    }

    To Authorize User

    Global.asax class enables to hook into Authorize

    public void Application_Authorize(object sender, EventArgs e){
         var user = Context.User;
         if(user == null)   
             return;
    
         FormsIdentity formsIdentity = user.Identity as FormsIdentity;
         long userSessionID = long.Parse(formsIdentity.UserData);
    
         string cacheKey = "US-" + userSessionID;
    
         // caching to improve performance
         object result = HttpRuntime.Cache[cacheKey];
         if(result!=null){
             // if we had cached that user is alright, we return..
             return;
         }
    
         // hit the database and check if session is alright
         // If user has logged out, then all UserSessions should have been
         // deleted for this user
         UserSession session = db.UserSessions
               .FirstOrDefault(x=>x.UserSessionID == userSessionID);
         if(session != null){
    
              // update session and mark last date
              // this helps you in tracking and you
              // can also delete sessions which were not
              // updated since long time...
              session.DateUpdated = DateTime.UtcNow;
              db.SaveChanges();
    
              // ok user is good to login
              HttpRuntime.Cache.Add(cacheKey, "OK", 
                   // set expiration for 5 mins
                   DateTime.UtcNow.AddMinutes(5)..)
    
             // I am setting cache for 5 mins to avoid
             // hitting database for all session validation
             return;
         }
    
         // ok validation is wrong....
    
    
         throw new UnauthorizedException("Access denied");
    
    }

    When User Logs out

    public void Logout(){
    
        // get the ticket..
        FormsIdentity f = Context.User.Identity as FormsIdentity;
        long sessionID = long.Parse(f.UserData);
    
        var session = db.UserSessions.First(x=>x.UserSessionID = sessionID);
        db.UserSession.Remove(session);
        db.SaveChanges();
    
        FormsAuthentication.Signout();
    }

    ** When user changes password or user is blocked or user is deleted... **

    public void ChangePassword(){
    
        // get the ticket..
        FormsIdentity f = Context.User.Identity as FormsIdentity;
        long sessionID = long.Parse(f.UserData);
    
        var session = db.UserSessions.First(x=>x.UserSessionID = sessionID);
    
        // delete all sessions for the same user id
        // this will force user to relogin on all other
        // devices...
        db.Database.ExecuteSql(
            "DELETE FROM UerSessions WHERE UserID=@UserID",
            new SqlParameter("@UserID", session.UserID));
    }
  • 相关阅读:
    Hibernate的游离态与持久态转换
    怎样区分直连串口线和交叉串口线?
    JAVA 内存泄露的理解
    leetcode第一刷_Validate Binary Search Tree
    Java程序猿的JavaScript学习笔记(8——jQuery选择器)
    Android二维码开源项目zxing用例简化和生成二维码、条形码
    Android Service 服务(一)—— Service
    一个简单的文本编辑器。(是在DEV C++下写的)
    我的Hook学习笔记
    ios网络学习------8 xml格式数据的请求处理 用代码块封装
  • 原文地址:https://www.cnblogs.com/chucklu/p/13164460.html
Copyright © 2011-2022 走看看