One possibility is to use a session variable. Another one is to persist this information in the userData
part of the authentication ticket which is stored in the cookie. Then you could write a custom principal and authorize attribute which will read the authentication cookie, decrypt the ticket and retrieve the information.
UPDATE:
As requested in the comments section here's an example of how the second approach could be implemented.
We start with defining a custom principal:
public class CustomPrincipal : GenericPrincipal
{
public CustomPrincipal(IIdentity identity, string[] roles, string businessId)
: base(identity, roles)
{
BusinessId = businessId;
}
public string BusinessId { get; private set; }
}
then a custom authorize attribute:
public class CustomAuthorize : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (isAuthorized)
{
var cookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
var ticket = FormsAuthentication.Decrypt(cookie.Value);
var identity = new GenericIdentity(ticket.Name);
var principal = new CustomPrincipal(identity, null, ticket.UserData);
httpContext.User = principal;
}
return isAuthorized;
}
}
next we need to modify the login action so that the business id is included in the userData part of the authentication cookie:
[HttpPost]
public ActionResult LogOn(string username, string password)
{
SomeUserModel user = FetchUserFromSomewhere(username, password);
if (user == null)
{
// wrong username/password => redisplay login form
return View();
}
var ticket = new FormsAuthenticationTicket(
1,
username,
DateTime.Now,
DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),
false,
user.BusinessId // that's where we store the business id
);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
{
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL
};
Response.AppendCookie(cookie);
return RedirectToAction("Index", "SomeController");
}
}
And the last part is to use the custom authorize attribute on some action:
[CustomAuthorize]
public ActionResult Foo()
{
var businessId = ((CustomPrincipal)User).BusinessId;
...
}
You could write a base controller and expose this custom principal as a property to avoid casting everytime you need to access the business id.