MVC4 SimpleMemberhip Intranet webapp with Custom Roles - asp.net-mvc-4

I am using SimpleMembership with WebMatrix. Since its an Intranet webapp, I am using the exisitng domain users in combination with custom roles and storing them in local webpages_ tables. I am trying to develop classes to manage the users & roles. Perhaps I am going about this the wrong way, but here is what I have and below where I am stuck.
Setting this in global.asa
WebSecurity.InitializeDatabaseConnection("SqlRoleManagerConnection", "webpages_Users", "UserID", "Username", false);
Setting this in web.config (other sources said to add roleManager=true section but it currently works without it)
<!--<roleManager enabled="true" defaultProvider="SqlRoleManager">
<providers>
<clear />
<add name="SqlRoleManager" type="System.Web.Security.SqlRoleProvider" connectionStringName="SqlRoleManagerConnection" applicationName="YourAppName" />
</providers>
</roleManager>-->
<httpRuntime targetFramework="4.5" />
<authentication mode="Windows" />
<authorization>
<allow roles="Managers" />
<allow users="?" />
</authorization>
Data Access class (used by controllers)
public class Membership
{
private OFACDB _db = new OFACDB();
public string UserID { get; set; }
public string UserName { get; set; }
public string RoleName { get; set; }
public string Name { get; set; }
public const string Domain = "LAN\\";
public void Delete()
{
Roles.RemoveUserFromRole(this.UserName, this.RoleName);
}
public void AddMemberToRole()
{
if (!Roles.IsUserInRole(Membership.Domain + this.UserName, this.RoleName))
Roles.AddUserToRole(Membership.Domain + this.UserName, this.RoleName);
}
public void AddMember()
{
webpages_Users member = new webpages_Users();
member.Username = Membership.Domain + this.UserName;
_db.webpages_Users.Add(member);
_db.SaveChanges();
}
public void DelMember(string id)
{
webpages_Users member = _db.webpages_Users.Find(id);
_db.webpages_Users.Remove(member);
_db.SaveChanges();
}
}
public class MembershipViewModel : List<Membership>
{
private OFACDB _db = new OFACDB();
//public List<webpages_Users> UserView { get; set; }
public IQueryable<webpages_Users> GetAllRecords()
{
var view = _db.webpages_Users
.OrderBy(v => v.Username);
return view;
}
public void GetAllRoleUsers(string role) //Get application's users
{
if (Roles.RoleExists(role))
{
foreach (var item in Roles.GetUsersInRole(role))
{
var user = new Membership();
user.UserName = item;
user.Name = item;
user.RoleName = role;
this.Add(user);
}
}
}
public void GetNetworkUsers() //Get Network Users (AD)
{
var domainContext = new PrincipalContext(ContextType.Domain);
var groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, "Domain Users");
foreach (var item in groupPrincipal.Members)
{
var user = new Membership();
user.UserName = item.SamAccountName;
user.Name = item.Name;
this.Add(user);
}
}
}
And controller controls access by roles
[Authorize(Roles = "Admins")]
public ActionResult Index()
{
var users = new MembershipViewModel();
users.GetAllRoleUsers("Managers");
return View(users);
}
ADVICE?
I use Roles.GetUsersInRole to list out users in a role, but I can't delete them very easily as this call does not return UserIDs and if I use the username to find/delete record, then it is escaped in the URL because the usernames contain the domain\ characters.
/Account/Delete/LAN%5CLAN%5Ctest
Looking for advice on perhaps taking a different approach to these classes if anyone else has done this before. Do i need to use a Membership Provider and Role Provider?

We recently worked on a membership implementation that required Roles management and came across a nuget package called Security Guard.
http://www.mvccentral.net/Story/Details/tools/kahanu/securityguard-nuget-package-for-asp-net-membership
I will note right away that this package was not built to work with the SimpleMembership provider. SMP includes a basic subset of functionality which makes editing user records difficult. However, despite the limitations of SMP we were still able to combine native registrations, OAuth registration and roles management after customizing the functionality.

I wanted to make a comment only but I couldn't because I only have a lowly 44 points rep.
I know this is old but I was looking for the same thing and wanted to add to the comments above between the #Vic which has his own DB vs. #Pabloker which uses the builtin DB. I guess asp.net has its own script in creating this database and is explained in this blog
cd \Windows\Microsoft.NET\Framework64\v4.0.30319
.\aspnet_regsql -C "Data Source=localhost;Database=ACME.Config;Integrated Security=True;" -A r

Related

ASP.NET CORE Add easily accessible properties to logged user

In our Asp.Net Core (2.2) MVC project we had to use an existing database (including all user & role related tables) from our previous Asp.Net Web app project.
Retrieving user data in asp.net web app (and having it available throughout the website) was preatty simple: upon login fill a custom user class/object with all the properties you need, save it as a Session variable and you call it wherever you need it (without going to the database).
This seems to me a lot harder to achieve in Asp.Net Core. What I have so far is:
ApplicationUser class:
public class ApplicationUser : IIdentity
{
public int Id { get; set; }
public Uporabnik Uporabnik { get; set; }
public string AuthenticationType { get; set; }
public bool IsAuthenticated { get; set; }
public string Name { get; set; }
}
Login form:
public IActionResult Prijava(PrijavaModel model)
{
// check user credentials
//
// ... validation code here ...
//
if (uporabnik != null)
{
//Create the identity for the user
var identity = new ClaimsIdentity(new[] {
new Claim("Email", model.Email),
new Claim("Id", uporabnik.IdWebUser.ToString()),
new Claim("Name", uporabnik.ImeInPriimek),
new Claim(ClaimTypes.Name, uporabnik.ImeInPriimek),
new Claim(ClaimTypes.PrimarySid, uporabnik.IdWebUser.ToString())
}, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
var login = HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
return RedirectToAction("Index", "Home");
}
return View();
}
Now to retrieve the data in a controller I have to do something like this:
// id
int idUser = int.Parse(#User.Claims.FirstOrDefault(x => x.Type == "Id").Value);
// or email
string email = #User.Claims.FirstOrDefault(x => x.Type == "Email").Value;
Well, this all works fine, but it's definitely not practical. To access any other user data I can go to the database (by "ID") and retrieve it, but I don't think this is the right way to do it!?!
Can I expand the identity class in such a way that I can set the extra properties I need at login time and retrive in a fashion similar to something like this:
var property1 = #User.Property1;
var property2 = #User.Property2;
// or
var property1 = #User.MyExtraProperties.Property1;
var property2 = #User.MyExtraProperties.Property2;
Is it possible (and also keeping it simple)?
EDIT: since there are no answers/suggestions, can I do the same thing with a different approach?
Look like you only want to call your properties in a better way?
public class ApplicationUser : IdentityUser
{
public string CustomName { get; set; }
}
Assuming you have done adding your extra properties, you could create an extension method for your properties, so you can later call them like User.Identity.GetCustomName().
namespace Project.Extensions
{
public static class IdentityExtensions
{
public static string GetCustomName(this IIdentity identity)
{
var claim = ((ClaimsIdentity)identity).FindFirst("CustomName");
return (claim != null) ? claim.Value : string.Empty;
}
}
}
Note that I didn't include the part where you add the claims, because you already have it. In this case, you should have CustomName claim.
Also, #Dementic is right about the session. If a user is removed/disabled, he would still have access to. So, having a db call each time you need to fetch information is correct.

How to extend IdentityUser as a claim in ASP.NET Core / MVC 6 / EF7?

I am building a site that has Users that belong to an Account. The account is identified by an AccountId which is a foreign key for most data in the DB such as Charges (associated to an Account) or Receipts (associated to an Account).
Rather than hitting the DB every time the repository needs to be polled for data to get the user's AccountId, I wanted to add the AccountId as a claim. The goal being to do something like:
_repository.GetAllChargesByAccountId(User.Identity.GetAccountId());
I'm finding only tidbits and partial solutions for this and I haven't been able to resolve some differences between those examples and my specific environment (ASP.NET Core RC1, MVC 6, EF7).
I have derived a class from IdentityUser for adding attributes about the user:
public class UserIdentity : IdentityUser {
public static object Identity { get; internal set; }
public int AccountId { get; set; }
}
I have created a UserIdentityContext that derives from IdentityDbContext that I'm using for my EF user store.
And I have the following AuthController:
public class AuthController : Controller {
private SignInManager<UserIdentity> _signInManager;
public AuthController(SignInManager<UserIdentity> signInManager) {
_signInManager = signInManager;
}
public IActionResult Login() {
if (User.Identity.IsAuthenticated)
return RedirectToAction("Dashboard", "App");
return View();
}
[HttpPost]
public async Task<ActionResult> Login(LoginViewModel vm, string returnUrl) {
if (ModelState.IsValid) {
var signInResult = await _signInManager.PasswordSignInAsync(vm.Username, vm.Password, true, false);
if (signInResult.Succeeded) {
if (String.IsNullOrWhiteSpace(returnUrl))
return RedirectToAction("Dashboard", "App");
else return RedirectToAction(returnUrl);
} else {
ModelState.AddModelError("", "Username or password is incorrect.");
}
}
return View();
}
public async Task<IActionResult> Logout() {
if (User.Identity.IsAuthenticated) {
await _signInManager.SignOutAsync();
}
return RedirectToAction("Index", "App");
}
}
Looking at other posts, it sounds like I need to add an IdentityExtension in order to access the claim as User.Identity.GetAccountId() and generate a custom user identity as in this answer: How to extend available properties of User.Identity but obviously this is done in an older version and many of the method calls are not applicable anymore.
Thanks in advance for any answers or guidance.
if you have added a claim for AccountId you can then easily write an extension method to get it:
public static string GetAccountId(this ClaimsPrincipal principal)
{
if (principal == null)
{
throw new ArgumentNullException(nameof(principal));
}
var claim = principal.FindFirst("AccountId");
return claim != null ? claim.Value : null;
}
if you need help on how to add a custom claim see this question

Authorise attribute using active directory role provider MVC4

I am currently using the AspNetWindowsTokenRoleProvider to provide the authorization for my controller actions:
[Authorize(Roles = "domain\\group")]
public ActionResult Index()
{
code.....
}
Rather than hard code the role name ("domain\group"), or use a constant. I would like to be to replace it with a call to a settings class which will get it from a database or file.
I figure that either there is a way to do this built into the provider or I need to replace the provider with my own implementation.
I have drawn a blank googling, so I guess I am not asking the right questions!
Could anyone please point me in the right direction to achieve this.
Thanks
I kind of worked it out, so here is the solution in case anyone wants to do the same thing.
Create a new class inheriting from WindowsTokenRoleProvider
public class MyADProvider : WindowsTokenRoleProvider
{
//settings key
public const string Users = "Authorisation.AdGRoup.Users";
public const string Admins = "Authorisation.AdGRoup.Admins";
private ISettingsRepository settingsRepository;
public override string[] GetRolesForUser(string username)
{
// settings repository reads from settings file or DB
// actual implementation is up to you
this.settingsRepository = new SettingsRepository();
// get all the AD roles the user is in
var roles = base.GetRolesForUser(username);
List<string> returnedRoles = new List<string>
{
this.GetADRole(roles, Admins),
this.GetADRole(roles, Users)
};
return returnedRoles.ToArray();
}
private string GetADRole(string[] usersAdRoles, string roleSettingName)
{
//Get the actual name of the AD group we want from the settings
var settingName = this.settingsRepository.GetSetting(roleSettingName);
return usersAdRoles.Contains(settingName) ? roleSettingName : string.Empty;
}
}
Then change the web.config to use the new class:
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
<providers>
<clear />
<add name="AspNetWindowsTokenRoleProvider" type="MyADProvider" applicationName="/" />
</providers>
</roleManager>
Then I can use the settings key in the code:
[Authorize(Roles = MysADProvider.Admins)]
public ActionResult Index()
{}

SimpleMembership in MVC4 app + WebApi using basic HTTP auth

I'm trying to implement an MVC4 web application with the following requirements:
(a) it offers its services to authenticated users only. As for authentication, I'd like to use simple membership, as it is the latest authentication technique from MVC, gives me the advantage of defining my own db tables, provides OAuth support out of the box, and is easily integrated with both MVC and WebApi.
(b) it exposes some core functions via WebApi for mobile/JS clients, which should be authenticated via basic HTTP authentication (+SSL). Typically I'll have JS clients using jQuery AJAX calls to WebApi controllers, decorated with the Authorize attribute for different user roles.
(c) ideally, in a mixed environment I would like to avoid a double authentication: i.e. if the user is already authenticated via browser, and is visiting a page implying a JS call to a WebApi controller action, the (a) mechanism should be enough.
Thus, while (a) is covered by the default MVC template, (b) requires basic HTTP authentication without the mediation of a browser. To this end, I should create a DelegatingHandler like the one I found in this post: http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers.
The problem is that its implementation requires some way of retrieving an IPrincipal from the received user name and password, and the WebSecurity class does not provide any method for this (except Login, but I would avoid changing the logged user just for the purpose of authorization, also because of potential "mixed" environments like (c)). So it seems my only option is giving up simple membership. Does anyone have better suggestions? Here is the relevant (slightly modified) code from the cited post:
public interface IPrincipalProvider
{
IPrincipal GetPrincipal(string username, string password);
}
public sealed class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
public class BasicAuthMessageHandler : DelegatingHandler
{
private const string BasicAuthResponseHeader = "WWW-Authenticate";
private const string BasicAuthResponseHeaderValue = "Basic";
public IPrincipalProvider PrincipalProvider { get; private set; }
public BasicAuthMessageHandler(IPrincipalProvider provider)
{
if (provider == null) throw new ArgumentNullException("provider");
PrincipalProvider = provider;
}
private static Credentials ParseAuthorizationHeader(string sHeader)
{
string[] credentials = Encoding.ASCII.GetString(
Convert.FromBase64String(sHeader)).Split(new[] { ':' });
if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) ||
String.IsNullOrEmpty(credentials[1])) return null;
return new Credentials
{
Username = credentials[0],
Password = credentials[1],
};
}
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
AuthenticationHeaderValue authValue = request.Headers.Authorization;
if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter))
{
Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
if (parsedCredentials != null)
{
Thread.CurrentPrincipal = PrincipalProvider
.GetPrincipal(parsedCredentials.Username, parsedCredentials.Password);
}
}
return base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
var response = task.Result;
if (response.StatusCode == HttpStatusCode.Unauthorized
&& !response.Headers.Contains(BasicAuthResponseHeader))
{
response.Headers.Add(BasicAuthResponseHeader,
BasicAuthResponseHeaderValue);
}
return response;
});
}
}
Here is another solution that meets all of your requirements. It uses SimpleMemberhsip with a mix of forms authentication and basic authentication in an MVC 4 application. It can also support Authorization, but it is not required by leaving the Role property null.
Thank you, this seems the best available solution at this time!
I managed to create a dummy solution from scratch (find it here: http://sdrv.ms/YpkRcf ), and it seems to work in the following cases:
1) when I try to access an MVC controller restricted action, I am redirected to the login page as expected to get authenticated.
2) when I trigger a jQuery ajax call to a WebApi controller restricted action, the call succeeds (except of course when not using SSL).
Yet, it does not work when after logging in in the website, the API call still requires authentication. Could anyone explain what's going here? In what follows I detail my procedure as I think it might be useful for starters like me.
Thank you (sorry for the formatting of what follows, but I cannot manage to let this editor mark code appropriately...)
Procedure
create a new mvc4 app (basic mvc4 app: this already comes with universal providers. All the universal providers class names start with Default...);
customize web.config for your non-local DB, e.g.:
<connectionStrings>
<add name="DefaultConnection"
providerName="System.Data.SqlClient"
connectionString="data source=(local)\SQLExpress;Initial Catalog=Test;Integrated Security=True;MultipleActiveResultSets=True" />
Also it's often useful to set a machineKey for hashing passwords, so that you can freely move this site around from server to server without having your passwords scrambled. Use a machine key generator website to define an entry like this:
<system.web>
<machineKey
validationKey="...thekey..."
decryptionKey="...thekey..."
validation="SHA1"
decryption="AES" />
if required create a new, empty database corresponding to the connection string of your web.config. Then start our good old pal WSAT (from VS Project menu) and configure security by adding users and roles as required.
if you want to, add a HomeController with an Index action, because no controller is present in this template and thus you could not test-start your web app without it.
add Thinktecture.IdentityModel.45 from NuGet and add/update all your favorite NuGet packages. Notice that at the time of writing this, jquery validation unobtrusive from MS is no more compatible with jQuery 1.9 or higher. I rather use http://plugins.jquery.com/winf.unobtrusive-ajax/ . So, remove jquery.unobtrusive* and add this library (which consists of winf.unobtrusive-ajax and additional-methods) in your bundles (App_Start/BundleConfig.cs).
modify the WebApiConfig.cs in App_Start by adding it the code after the DefaultApi route configuration:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// added for Thinktecture
var authConfig = new AuthenticationConfiguration
{
InheritHostClientIdentity = true,
ClaimsAuthenticationManager = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager
};
// setup authentication against membership
authConfig.AddBasicAuthentication((userName, password) => Membership.ValidateUser(userName, password));
config.MessageHandlers.Add(new AuthenticationHandler(authConfig));
}
}
To be cleaner, the api controllers will be placed under Controllers/Api/, so create this folder.
Add to models a LoginModel.cs:
public class LoginModel
{
[Required]
[Display(Name = "UserName", ResourceType = typeof(StringResources))]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password", ResourceType = typeof(StringResources))]
public string Password { get; set; }
[Display(Name = "RememberMe", ResourceType = typeof(StringResources))]
public bool RememberMe { get; set; }
}
This model requires a StringResources.resx resource (with code generation) I usually place under an Assets folder, with the 3 strings quoted in the attributes.
Add a ClaimsTransformer.cs to your solution root, like this:
public class ClaimsTransformer : ClaimsAuthenticationManager
{
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return base.Authenticate(resourceName, incomingPrincipal);
}
var name = incomingPrincipal.Identity.Name;
return Principal.Create(
"Custom",
new Claim(ClaimTypes.Name, name + " (transformed)"));
}
}
Add Application_PostAuthenticateRequest to Global.asax.cs:
public class MvcApplication : HttpApplication
{
...
protected void Application_PostAuthenticateRequest()
{
if (ClaimsPrincipal.Current.Identity.IsAuthenticated)
{
var transformer = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager;
var newPrincipal = transformer.Authenticate(string.Empty, ClaimsPrincipal.Current);
Thread.CurrentPrincipal = newPrincipal;
HttpContext.Current.User = newPrincipal;
}
}
}
web.config (replace YourAppNamespace with your app root namespace):
<configSections>
<section name="system.identityModel"
type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
...
add the other models for account controller, with their views (you can derive them from MVC3 application template, even if I prefer changing them to more localizable-friendly variants using attributes requiring string resource names rather than literals).
to test browser-based authentication, add some [Authorized] action to a controller (e.g. HomeController), and try accessing it.
to test basic HTTP authentication, insert in some view (e.g. Home/Index) a code like this (set your user name and password in the token variable):
...
<p>Test call
$(function() {
$("#test").click(function () {
var token = "USERNAME:PASSWORD";
var hash = $.base64.encode(token);
var header = "Basic " + hash;
console.log(header);
$.ajax({
url: "/api/dummy",
dataType: "json",
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", header);
},
success: function(data) {
alert(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
});
This requires the jQuery plugin for encoding/decoding Base64: jquery.base64.js and its minified counterpart.
To allow SSL, follow the instructions here: http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx (basically, enable SSL in the web project properties and connect to the port specified in the property value).
Maybe this helps - sounds this is like your scenario:
http://leastprivilege.com/2012/10/23/mixing-mvc-forms-authentication-and-web-api-basic-authentication/
http://leastprivilege.com/2012/10/24/extensions-to-the-web-apimvc-formsbasic-auth-sample-claims-transformation-and-ajax/

MVC 4 Intranet Authentication with Custom Roles

I have spent some time searching and found a lot of confusing answers, so I will post here for clarification.
I am using MVC4 VS2012 created an Intranet site using domain authentication. Everything works. However, to manage the users that have access to different areas of this webapp I prefer not to use AD groups that I cannot manage and nor can the users of the webapp.
Is there an alternative? I assume this would involve associating/storing domain names belonging to custom roles and using the Authorize attribute to control access.
[Authorize(Roles = "Managers")]
Can anyone suggest the best pattern for this or point me in the right direction?
I see a similar solution link, but I am still not sure how to use this against a stored list of roles and validate the user against those roles. Can anyone elaborate if this solution would work?
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;
}
}
I'm using this configuration with SQL Server and MVC3.
Web.config:
<system.web>
<roleManager enabled="true" defaultProvider="SqlRoleManager">
<providers>
<clear />
<add name="SqlRoleManager" type="System.Web.Security.SqlRoleProvider" connectionStringName="SqlRoleManagerConnection" applicationName="YourAppName" />
</providers>
</roleManager>
....
<authentication mode="Windows" />
....
<connectionStrings>
<add name="SqlRoleManagerConnection" connectionString="Data Source=YourDBServer;Initial Catalog=AppServices;Integrated Security=True;" providerName=".NET Framework Data Provider for OLE DB" />
</connectionStrings>
To inicialize roles:
Global.asax.cs
using System.Web.Security;
////
protected void Application_Start()
{
//You could run this code one time and then manage the rest in your application.
// For example:
// Roles.CreateRole("Administrator");
// Roles.AddUserToRole("YourDomain\\AdminUser", "Administrator");
Roles.CreateRole("CustomRole");
Roles.AddUserToRole("YourDomain\\DomainUser", "CustomRole");
}
In your Controller
[Authorize(Roles ="CustomRole")]
public class HomeController : Controller
{
To manage users
public class Usuario
{
public string UserName { get; set; }
public string RoleName { get; set; }
public string Name { get; set; }
public const string Domain = "YourDomain\\";
public void Delete()
{
Roles.RemoveUserFromRole(this.UserName, this.RoleName);
}
public void Save()
{
if (Roles.IsUserInRole(Usuario.Domain + this.UserName, this.RoleName) == false)
{
Roles.AddUserToRole(Usuario.Domain + this.UserName, this.RoleName);
}
}
}
Users Class
public class Usuarios : List<Usuario>
{
public void GetUsuarios() //Get application's users
{
if (Roles.RoleExists("CustomRole"))
{
foreach (string _usuario in Roles.GetUsersInRole("CustomRole"))
{
var usuario = new Usuario();
usuario.UserName = _usuario;
usuario.RoleName = "CustomRole";
this.Add(usuario);
}
}
//
public void GetUsuariosRed() //Get Network Users (AD)
{
var domainContext = new PrincipalContext(ContextType.Domain);
var groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, "Domain Users");
foreach (var item in groupPrincipal.Members)
{
var usuario = new Usuario();
usuario.UserName = item.SamAccountName;
usuario.Name = item.Name;
this.Add(usuario);
}
}
You can create an "Admin" controller like this, to manage the users:
[Authorize(Roles = "AdminCustomRole")]
public class AdminController : Controller
{
//
public ActionResult Index()
{
var Usuarios = new Usuarios();
Usuarios.GetUsuarios();
return View(Usuarios);
}
[HttpGet]
public ActionResult CreateUser()
{
var Usuarios = new Usuarios();
Usuarios.GetUsuariosRed();
return View(Usuarios);
}
//
In my application, custom roles are fixed.