15

I am trying to implement windows authentication in my ASP.NET MVC2 application. I've followed all the steps suggested by the official documentation:

<authentication mode="Windows" />

<authorization>
  <deny users="?" />
</authorization>

I've specified NTLM Authentication. So far so good. Everything works fine. I would like to check the users logged-in against my database. I would like to fetch roles from my table and then manage the authorization using a custom attribute.
I don't want to use membership and roles provider. I'already have my tables Users/Roles in place cause they've been used for an Internet App (this is the Intranet App).

In my Internet App I had a form where the user inputs the data. The form is posted to a controller which checks everything and creates a cookie with the user (and roles) of the logged-in user.

In my global.asax I've trapped the AuthenticateRequest event where I read the cookie and create a custom principal which I use all over the app to check the authorizations.

How can I do implement this with Windows Authentication?

2 Answers 2

23

Just create a new principal and assign it to the user and thread in Global.asax (or use an action filter).

protected void Application_AuthenticateRequest(object sender, EventArgs args)
{
  if(HttpContext.Current != null)
  {
     String [] roles = GetRolesFromSomeDataTable(HttpContext.Current.User.Identity.Name);

     GenericPrincipal principal = new GenericPrincipal(HttpContext.Current.User.Identity, roles);

     Thread.CurrentPrincipal = HttpContext.Current.User = principal;
  }
}

If a user doesn't have any role that matches, they can be barred from the app using the web.config authoirzation element:

<authorization>
  <allow roles="blah,whatever"/>
  <deny users="*"/>               
</authorization>
Sign up to request clarification or add additional context in comments.

8 Comments

@Xhalent: Yes,but ... where ...?
Modify your web config authorization element to restrict user to those with certain roles. I'll put the example in the post.
Becuase CAS (Code Access Security) work against the Thread Principal which is not kept in sync if you only update the HttpContext.User. This means declarative attributes such as PrincipalPermission etc will not be evaluated against your intended principal. Best practice is to update both at once.
Sorry, and this might be an asinine question... But would this not query the db and rebuild the principal on every authenticated request? Or do I misunderstand how Application_AuthenticateRequest gets fired...
Yes this is called on every authorize request. It's also creating a new principal every time for the current thread. Some mix Windows and Forms Authentication (cookie) for this purpose.
|
6

Just to add to the above answer, Hope this save some fokes some time.

I have a intranet MVC 5 site with VS 2015.

The code did not work for me until the top line was updated with HttpContext.Current.User. The site was giving me null reference to the HttpContext.Current.User if the user wasn't already created in the Database. By adding .User to the first line, it bypassed that code on first load and worked.

if (HttpContext.Current.User != null)
        {


            String[] roles = GetRolesFromSomeDataTable(HttpContext.Current.User.Identity.Name);

            GenericPrincipal principal = new GenericPrincipal(HttpContext.Current.User.Identity, roles);

            Thread.CurrentPrincipal = HttpContext.Current.User = principal;
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.