Asp.net mvc authentication vs shibboleth and authorization
Shibboleth publishes user attributes associated with sessions in HTTP request headers based on the header names defined in the Attribute Acceptance Policy (1.3.x) or Attribute Mapping (2.x) files. These headers are converted to CGI variables based on the mapping rules defined in the CGI specification.
You should be aware of this safety tip: http://shibboleth.net/community/advisories/secadv_20090615.txt
I've never used shibboleth, but you can get user information from the Controller.User property. It will return the general principle of the current thread. Using this principle, you can check if the user is authenticated and get the username. This is because after login, an authentication cookie is set and this cookie contains a limited amount of information. And on every request after login, only this cookie is checked (if it exists and is valid - the user is authenticated).
So if you need specific information, you can manually load the user (better use the cache here) and check what you want.
Also you can create and attach your own principal with the necessary information to the thread when the request starts (for example, when starting the request, load the user from db / cache using the username from the base principal, create and install your own manager in the thread). After that you can check all the properties of the user you need.
a source to share
You want to create a method in Global.asax.cs that has the following signature
protected void Application_PostAuthenticateRequest()
{
//Your code here.
}
This will be called automatically before doing anything else (MVC will call this method if it exists, you don't need to "include it" anywhere) and this is where you need to set the Principal. For example, suppose you have a title with a name RolesHeader
that has a comma separated value for roles and another title UserId
that has a (duh) user id.
Your code without error handling might look something like this:
protected void Application_PostAuthenticateRequest()
{
var rolesheader = Context.Request.Headers["RolesHeader"];
var userId = Context.Request.Headers["UserId"];
var roles = rolesheader.Split(',');
var principal = new GenericPrincipal(new GenericIdentity(userId), roles);
Context.User = principal;
}
This is the Principal / Identity that the attribute uses [Authorize]
, so setting it here at the start of the request lifecycle means the attribute [Authorize]
will work correctly.
The rest of this parameter is optional, but I recommend:
I like to create my own custom classes that implement IPrincipal and IIdentity instead of using GenericPrincipal and GenericIdentity, so I can add more user information to it. My custom Principal and Identity objects then have much richer information like branch numbers or email addresses or whatever.
Then I create a controller called BaseController
which has the following
protected new CustomPrincipal User
{
get
{
return (base.User as CustomPrincipal) ?? CustomPrincipal.GetUnauthorizedPrincipal();
}
}
This allows me to access all of my rich, regular master data instead of what is defined in IPrincipal. All my real controllers then inherit from BaseController
, not directly from Controller
.
Obviously, when using a normal principal in the Application_PostAuthenticateRequest () method, you must set the Context.User as CustomPrincipal
instead GenericPrincipal
.
a source to share