0

We have an Intranet site we are developing in ASP.NET 5 aka vNext and MVC 6.

We'd like to be able to get the Windows Network ID the user is logged in as, but then there is an existing database defining roles, etc. we were going to leverage and have already done so. Really all I want to do is get the Windows user ID while using ASP.NET Identity to manage roles the user has access to. Any suggestions how to accomplish this?

Essentially in Startup.cs I have something like below in Configure Services:

    services.AddIdentity<WorldUser, IdentityRole>(config =>
    {
       config.User.RequireUniqueEmail = true;
       config.Password.RequiredLength = 8;
    }).AddEntityFrameworkStores<WorldContext>();

Next in Configure I have: app.UseIdentity();

Windows Authentication is on at the project properties level and so is Anonymous. I see no way to actually get the Windows User ID.

Brian Edwards
  • 403
  • 6
  • 15
  • I am going to delete my answer, since it does not work. But I do not want it to look like I am shirking my commitment, so... As soon as the 48 hours SO initial wait is over, and I am allowed to start a bounty, I will start a bounty and award 100 rep points to the first person to have answered this correctly, whether the answer comes before or after the bounty. –  Oct 22 '15 at 20:36
  • Brian, have you looked at this http://stackoverflow.com/a/10584919/4843530. Let me know if it helps, as I will want to try to work it out. Seems like we have a very similar need and problem. –  Oct 22 '15 at 21:48
  • Sorry I missed this earlier. It was a good thought but running the code under IIS Express, that code "var username = Thread.CurrentPrincipal.Identity.Name;" just returns an empty string for User Name. There may be a way to go into the IIS Express config file to make it return the Windows ID. Will try that too. – Brian Edwards Oct 23 '15 at 18:42

2 Answers2

0

Warning: this is code for ASP.NET 4.5 not 5.

Put this is your web.config:

<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" maxRequestLength="20480" />
    <authentication mode="Windows" />
    <authorization>
        <deny users="?" />                  <!--Denies access to the anonymous user.-->
        <allow users="MydomainName\MyUsername" />      <!--Grants access to this user.-->
        <allow roles="MyWindowsGroup" />
        <deny users="*" />                  <!--Denies access to everyone. This shakes out as everyone except the defined users/usergroupt that are rganted access manualy.-->
    </authorization>
</system.web>

This way you must have an Windows Network User Id. Which a user always has in an intranet application. Then just use:

HttpContext.Current.User.Identity.Name

Just as before. Like this:

String name = User.Identity.Name;
// If needed filter out the domain name here
int accessLevel = _UserRepository.GetAccessLevel(name) 
// Assuming  you use a repository to connect to your database. And also have a method to get the accesslevel for a username
Session["AccessLevel"] = accessLevel;
// In case you want to check for accesslevel in the views as well you can put it in a session like so.

Once again this is code for a .NEET 4.5 and NOT a .NET 5 Application. The C# code should be identical but there is no web.config in .NET 5 so you have to put your config in via Startup.cs.

From what you are asking this seems like what you need, if any further explanation is required let me know.

Teun Vos
  • 584
  • 5
  • 9
  • This does not work because as long as Allow Anonymous is true, it never gets the Windows Network ID passed in. So IsAuthenticated is always false. If I set Allow Anonymous to false and Windows Authentication to True, then isAuthenticated is always true and the user ID is always there, but then all the role management features of .Net Identity get ignored. I am going to edit my posting a little. – Brian Edwards Oct 22 '15 at 20:32
  • It is possible to acieve what u want by using just Windows authentication instead of .NET authentication. Is there a specific reason you want .NET authentication instead of Windows? EDIT: If you I can provide you with an working example. – Teun Vos Oct 22 '15 at 20:42
  • I guess I want the best of both worlds. I don't want a user authenticated to the network to have to enter their User ID and Password a 2nd time (actually it is a requirement). But then the existing database has all the role information as well as some business logic to derive roles. I was able to implement a custom Asp.Net Identity provider which works great as long as I have a login form where I re-enter credentials and then confirm via LDAP the ID and password are correct. – Brian Edwards Oct 22 '15 at 21:18
  • If you have a working example you can provide, I would love it. – Brian Edwards Oct 22 '15 at 21:18
  • Also note, this is an ASP.NET 5 application which means there is no web.config anymore. Nor is there a Global.asax. Just a Startup class to register services. There has to be a good way to do this somewhere. – Brian Edwards Oct 22 '15 at 21:21
  • I am litteraly in bed right now, I will send the example your way tomorrow (in about ten hours). – Teun Vos Oct 22 '15 at 21:21
  • Ah, I see. Then my exaple may need SOME changes. Not much since most of it is still in HttpContext. I can help you modify it if needed. – Teun Vos Oct 22 '15 at 21:22
  • Teun, hope you had some good rest, if you have a moment, please send your example. I have another solution I am working on now where I will override the AuthorizeAttribute with my own code, but I am hoping for an even better solution than mine. – Brian Edwards Oct 23 '15 at 12:28
  • I removed my original answer and put the ASP.net 4.5 solution in it. – Teun Vos Oct 23 '15 at 13:30
  • Thanks but I am afraid, that too will not work. The goal is to use the Authorize("Roles = "). When you use Windows Authentication that attribute tries to get roles from Active Directory which simply isn't where we keep our information. Therefore I am going to try another approach. – Brian Edwards Oct 23 '15 at 18:00
0

So I am still hoping someone comes up with a better answer because my goal is still to use and leverage .Net Identity for authorization after authenticating the user with their Windows User ID. But for now, I am going to enable Windows Authentication and use the solution for customizing Authorization options provided by Rick in this thread: How do you create a custom AuthorizeAttribute in ASP.NET Core?

So I will be doing the following, for each role creating a class as follows:

    public class ETimeAdmin : AuthorizationHandler<ETimeAdmin>, IAuthorizationRequirement
    {
       protected override void Handle(AuthorizationContext context, ETimeAdmin requirement)
       {



       }
    }

Then in Startup.cs in configure services I will add:

    services.AddAuthorization(options => options.AddPolicy("ETimeAdmin", policy => policy.Requirements.Add(new ETimeAdmin())));

Finally I should be able to use:

    [Authorize(Roles="ETimeAdmin")]

Instead of doing the above, what I'd like to do in Startup.cs is add this line:

     services.AddIdentity<ETimeUser, IdentityRole>(config =>
     {
     }).AddEntityFrameworkStores<ETimeContext>();

Then I could just use what is already provided with .Net Identity without writing my own code for each role. I'd have to employ my own caching so I wouldn't need to go back to the database each time I wanted to check if the user had permissions. There has to be a better way...

Community
  • 1
  • 1
Brian Edwards
  • 403
  • 6
  • 15