简体   繁体   中英

Retrieving the current logged in user's Id in a class library outside of an ASP.NET Webforms App using forms authentication

Currently in every one of my model classes I am doing the following in the constructor.

    public Product()
    {
        CreatedBy = System.Threading.Thread.CurrentPrincipal.Identity.Name;
        ModifiedBy = System.Threading.Thread.CurrentPrincipal.Identity.Name;
    }

This way when saving/updating records these values will always be set.

However, I want to switch my application from using the logged in user's name which the above gets me, to using the logged in user's Id.

With forms authentication what is the best way to retrieve additional data about the current logged in user without using Session? I noticed you can pass additional data when creating the forms auth cookie as soon as the user logs in, but I would have no idea how to retrieve it.

Here is the solution I came up with. I would appreciate any comments or suggestions. It feels kind of strange that everytime I create one of these model objects on the UI I need to pass the userId in the constructor:

public abstract class AuditableEntity : BaseEntity
{
    public DateTime CreatedDate { get; set; }
    public int? CreatedBy { get; set; }
    public DateTime ModifiedDate { get; set; }
    public int? ModifiedBy { get; set; }
}

public class Product : AuditableEntity
{
    public User(int userId)
    {
        this.CreatedBy = userId;
        this.ModifiedBy = userId;
    }

    public string ProductName { get; set; }
    public string SerialNumber { get; set; }
}

When authenticating an user, userYou can use FormsAuthenticationTicket to pass all cookie information and additional userData (string) to it, here is an example , then retrieve it by:

       FormsIdentity id = (FormsIdentity)User.Identity;
       FormsAuthenticationTicket ticket = id.Ticket;

       //those are label ids, that why they have Text property 
       cookiePath.Text = ticket.CookiePath;
       expireDate.Text = ticket.Expiration.ToString();
       expired.Text = ticket.Expired.ToString();
       isPersistent.Text = ticket.IsPersistent.ToString();
       issueDate.Text = ticket.IssueDate.ToString();
       name.Text = ticket.Name;
       userData.Text = ticket.UserData; // string userData you passed is HERE
       version.Text = ticket.Version.ToString();

More information

By the way, you should use HttpContext.Current.User.Identity.Name , take a look at this and this maybe this question .

You mentioned you have a lot of classes that have these CreatedBy and ModifiedBy properties.

Have them implement an interface:

interface IAuditableEntity
{
    int CreatedBy {get; set;}
    int ModifiedBy {get; set;}
}

public class Product : IAuditableEntity
{
    public string ProductName { get; set; }
    public string SerialNumber { get; set; }
    public int CreatedBy {get; set;}
    public int ModifiedBy {get; set;}
}
public class Vendor : IAuditableEntity
{
    public string VendorName{ get; set; }
    public string VendorNumber { get; set; }
    public int CreatedBy {get; set;}
    public int ModifiedBy {get; set;}
}

Create a centralized location in your web application responsible for communicating to the BLL that sets these properties for you.

public class BllLink
{
    public static void SaveEntity(IAuditableEntity entity)
    {
        entity.ModifiedBy = HttpContext.Current.User.Identity.Name;
        if(String.IsNullOrEmpty(entity.CreatedBy)) //assume new
        {
            entity.CreatedBy = HttpContext.Current.User.Identity.Name;
        }
        Bll.SaveEntity(entity); //you might need to use generics
    }
}

When you see repetitive code, it's a good candidate for simplification. Learning how to effectively utilize generics and interfaces will go a long ways towards that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM