4

I want to authenticate users in my asp.net mvc project using active directory, after hours and hours spent surfing on the internet i didn't find anything useful for me, I've already saw all the result but nothing.

I tryed to edit my web.config as many post suggests.

If anyone can help me with pieces of code or example i'll appreciate it a lot, because i have no idea where i can start from.

EDIT

My current web.config

<system.web>
<authentication mode="Forms">
  <forms name=".ADAuthCookie" loginUrl="~/MainMenu/Login" timeout="45" 
 slidingExpiration="false" protection="All" />
</authentication>
<authorization>
  <deny users="?" />
</authorization>
<membership defaultProvider="ADMembershipProvider">
  <providers>
    <clear />
     <add name="ADMembershipProvider" 
     type="System.Web.Security.ActiveDirectoryMembershipProvider"  
     connectionStringName="ADConnectionString" 
     attributeMapUsername="sAMAccountName" />
  </providers>
</membership>
</system.web>      
<connectionStrings>
 <add name="ADConnectionString" 
   connectioString="LDAP://myserver.mydomain.COM:389/DC=mydomain,DC=COM" />
</connectionStrings>

Leo

Leonardo Bassi
  • 184
  • 1
  • 2
  • 14
  • Ciao Leo, see this [Stackoverflow post](https://stackoverflow.com/questions/17224174/windows-authentication-for-asp-net-mvc-4-how-it-works-how-to-test-it) You simply need to set `` – Max Feb 12 '19 at 09:10
  • comment posted by @Max should solve your issue. however do you want to authenticate credentials submitted by the user against active directory?? – Gagan Deep Feb 12 '19 at 09:13
  • @GaganDeep yes, in particular i want to show views to user that belong to a specific group – Leonardo Bassi Feb 12 '19 at 10:06
  • @Max only add the tag? No more code? such as controllers, views..? – Leonardo Bassi Feb 12 '19 at 10:06
  • The solution provided by the answer (the tag) solve the problem *without* ask the user's credentials and by get the current window user. – Max Feb 12 '19 at 11:57
  • @Max i need to ask the username and pass to the user, because not everyone can go in some section – Leonardo Bassi Feb 12 '19 at 13:00
  • In that case you need to maintain users and roles tables in your application and only authenticate credentials posted by user against AD. I will provide the code to authenticate posted credentials against AD in the answer. – Gagan Deep Feb 13 '19 at 05:02

3 Answers3

3

I solved my problem setting view model and controller like this:

Model

public class LogOnModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }
}

Controller

public class AccountController : Controller
{
    public ActionResult LogOn()
    {
        return View();
    }

    [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/"))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("Main", "MainMenu");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect");
            }
        }

        // if we got this far, something failed, redisplay form
        return View(model);
    }

    public ActionResult LogOff()
    {
        FormsAuthentication.SignOut();

        return RedirectToAction("Login", "Account");
    }

View

<body id="bodyMain">
@using (Html.BeginForm("LogOn", null,FormMethod.Post))
{
<div class="container">
    @Html.ValidationSummary(true, "")
    <div style="padding-top:30%"></div>
    <table>
        <tr>
            <td>@Html.EditorFor(model => model.UserName)</td>
            <td>@Html.ValidationMessageFor(model => model.UserName, "",)</td>
        </tr>
        <tr></tr>
        <tr>
            <td>@Html.EditorFor(model => model.Password)</td>
            <td>@Html.ValidationMessageFor(model => model.Password, "")</td>
        </tr>
        <tr>
            <td>@Html.CheckBoxFor(model=>model.RememberMe)</td>               
        </tr>
    </table>
    <br />
    <button type="submit" class="btn btn-info">Login</button>
</div>
}

And the web.config remain the same as my question

Leonardo Bassi
  • 184
  • 1
  • 2
  • 14
1

As mentioned in the comments, it's as easy as changing your authentication method from Forms to Windows:

<authentication mode="Windows" />

That will work if the server you run this from is joined to the same domain as your users are logging in to, or a trusted domain. Users will not be prompted to login, as long as your site is setup as a trusted site (Intranet sites usually are).

To restrict parts of your application, you can use AuthorizeAttribute. For example, to restrict access to those in an AD group:

[Authorize(Roles="DOMAIN\GroupName")]

or, to restrict access to a specific AD user:

[Authorize(Users="DOMAIN\UserName")]

Multiple roles or users can be added by separating with a comma:

[Authorize(Roles="DOMAIN\Group1, DOMAIN\Group2")]

Those attributes can be applied to a whole controller, or to individual actions.

More information here.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • I am a bit confused, however i need a sort of form which the user have to insert his username and pass, after the validation of the credentials the user can navigate only in some sections, such as view details of something but not edit, ex: sample user, while admin can do everything. A sort of backend which allows to indicate which domain users can access with specific privileges. – Leonardo Bassi Feb 12 '19 at 14:57
  • The only reason to use a form where the user has to put in their username and password is if your server is not joined to the same domain as the users (or a trusted one). Is that your situation? – Gabriel Luci Feb 12 '19 at 15:06
  • No man, my computer is joined in the same domain of the server – Leonardo Bassi Feb 12 '19 at 15:11
  • Then use Windows Authentication :) it will make your life a whole lot easier. It validates their credentials for you, and you just use the `[Authorize]` attribute to lock down the controllers or actions you need to. – Gabriel Luci Feb 12 '19 at 15:14
  • Great, but after some consideration i concluded that i need also to log to the website with a different user or pc that isn't in the domain, if you have any idea where i can start i'll appreciate :) – Leonardo Bassi Feb 12 '19 at 15:33
  • That's tougher. You can either make everything Forms auth and [validate people's AD credentials yourself](https://stackoverflow.com/questions/290548/validate-a-username-and-password-against-active-directory), or you can use split Forms/Windows authentication to allow those with domain accounts to login automatically, but otherwise ask for credentials. – Gabriel Luci Feb 12 '19 at 15:45
1

If you need to Authenticate איק username and Password submitted by a user against AD, use the below code.

Add reference to System.DirectoryServices.AccountManagement

and in the code file

using System.DirectoryServices.AccountManagement;

Next, in your POST Method(flag is boolean type variable)

PrincipalContext pc = new PrincipalContext(ContextType.Domain, "DOMAINNAME");
            flag = pc.ValidateCredentials(UserName, Password);

If the flag is true, then credentials are valid otherwise they are not.

In this case, you need to manually set up the USER and roles (by using forms authentication), then you may restrict user/roles to display controller/views by using

[Authorize(Roles="RoleName")]
Grx70
  • 10,041
  • 1
  • 40
  • 55
Gagan Deep
  • 1,508
  • 9
  • 13
  • This code is for the controller right? It receives username and pass with Post from my login view, is this approach correct? – Leonardo Bassi Feb 13 '19 at 09:51
  • Hello, this post is old but I hope you can make something clear. In my case the authentication always fails if I use the constructor without username and password. If I use `new PrincipalContext(ContextType.Domain, "DOMAINNAME", ContextOptions.Negotiate, userName, password)`. Then, I can immediately call `UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, userName);`. If username or password is incorrect, `FindByIdentity` throws the exception. If they are correct, I can continue with the rest of the process, for example, setting the claims. Why is that? – jstuardo Oct 12 '22 at 12:58