I can't add ApplicationRoleManager to startup.auth - c#

The question is pretty simple, I'm trying to implement roles into my application, and most if not all places that I go to, tell me to use the following line in the startup.auth:
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
The problem is, Visual studio keeps telling me that ApplicationRoleManager doesn't exist! I already searched for different ways to maybe implement this, but everyone keeps saying "use ApplicationRoleManager", but I can't use it and apparently, I already got the libraries needed for it too.
Any help is very welcome here.
Apparently, my application didn't auto-generate the ApplicationRoleManager code, so i'm trying to add it manually. In IdentityConfig.Cs I have added the following code:
public class ApplicationRoleManager : RoleManager<IdentityRole>
{
public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore)
: base(roleStore)
{
}
}
At this point i'm stuck, because apparently I need other methods (like the create method) to make this work, but I cannot find any example of this code to add.
EDIT I am currently trying to implement a factory to implement the role management. But I'm having problems with VS not detecting certain objects, here's a picture to show it off better:
I have updated my identity packages in nuget, I'm still having problems with the libraries.

You are creating a factory to create the role manager. So the create method is the only method you should implement. But to be honest you don't need either if you don't want. So there are two ways of doing this:
app.CreatePerOwinContext<RoleManager<IdentityRole>>(new RoleManager<IdentityRole>(new RoleStore<IdentityRole, string>(new SomeContext()));
Or you can create a factory to do it for you:
public class RoleManagerFactory
{
private readonly IDbContextFactory<SomeContext> contextFactory
public RoleManagerFactory(IDbContextFactory<SomeContext> contextFactory)
{
this.contextFactory = contextFactory;
}
public RoleManager<IdentityRole> Create()
{
return new RoleManager<IdentityRole>(new RoleStore<IdentityRole, string>(contextFactory.Create()));
}
// If you have already instantiated a context to use, then you can pass it in here
public RoleManager<IdentityRole> Create(SomeContext context)
{
return new RoleManager<IdentityRole>(new RoleStore<IdentityRole, string>(context));
}
}
var factory = new RoleManagerFactory();
app.CreatePerOwinContext<RoleManager<IdentityRole>>(factory.Create());
I believe these ways are easier than what you are trying to do.
EDIT
I added the context factory in, because I remembered you need to pass a context into the role store. So EntityFramework already as a IDbContextFactory<TContext> interface, so you just need to create a concrete implementation and implement the interface, which is another Create method where you return a new context: new SomeContext().
This is what I do in my apps. In fact I use dependency injection and make the role manager be created per request. I use this factory so that I can inject the role manager into my classes:
public interface IRoleManagerFactory
{
RoleManager<IdentityRole> Create();
}
So in my classes I can do this:
public class RoleController : Controller
{
private readonly IRoleManagerFactory roleManagerFactory;
public RoleController (IRoleManagerFactory roleManagerFactory)
{
this.roleManagerFactory = roleManagerFactory;
}
// Create method
public async Task<JsonResult> CreateRole(string role)
{
using (var roleManager = this.roleManagerFactory.Create())
{
var result = await roleManager.CreateAsync(role);
return Json(new { succeeded: result.Succeeded });
}
}
}
EDIT
I have updated the example with correct usage of role manager and db context.

Related

How to inject a specific implementation in asp.net core

I have a Repository which has a dependency of User
I need to put other implementation of User and I can do it like that, but with this approach I do not know how to mock my repository
private readonly IRepository<Entity> _repository;
public SomeClass(MyAppDbContext context)
{
_repository= new EfRepository<WorkOrder>(context, new User());
}
Is there a way to inject a specific implementation of User here, or how I can test the code I wrote
Just as you inject MyAppDbContext into SomeClass you can also inject an instance of User, e.g.
private readonly IRepository<Entity> _repository;
public SomeClass(MyAppDbContext context, User user)
{
_repository= new EfRepository<WorkOrder>(context, user);
}
You can either register User in the IoC like this:
services.AddTransient<User>();
In case you have already registered a service for User and want to use another instance, you can register a factory method for SomeClass that sets up the User instance:
services.AddScoped<SomeClass>(prov => new SomeClass(
prov.GetRequiredService<MyAppDbContext>(),
new User()));
The factory method approach is viable if you only have a few spots that need the special instance, otherwise you can use this approach:
Unlike other IoCCs, the .NET Core IoCC does not support named registrations, but you can also use some kind of "marker interface" to register another instance:
public interface ISpecialUser : IUser {}
public class User : IUser
{
// ...
}
public class AnotherUser : ISpecialUser
{
// ...
}
// ...
public SomeClass(MyAppDbContext context, ISpecialUser user)
{
_repository= new EfRepository<WorkOrder>(context, user);
}
// ...
services.AddScoped<IUser, User>();
services.AddScoped<ISpecialUser, AnotherUser>();
In the tests, you can set up an instance of User that suits your needs and use the new constructor parameter.

Mock HttpContext.Current.User.Identity.Name

I'm currently writing unit test for my project where I'm using HttpContext.Current.User.Identity.Name at a defined time. Unfortunately, I can't make the test work since HttpContext is null when I run the test.
I already tried some solution I found on internet like Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("rmllcc"), new string[0]); but I can't get it work.
I'm using a Forms Authenticate system, xUnit with Moq. I'm not testing a controller but a Repository where I'm just logguing each time a user make use of a particular method. How could I accomplish this?
Listen to what your tests are telling you: use the fact that this test is hard to write to think about the structure of your code. You have introduced a dependency in your repository layer to the web application. That's not good. You also have two things going on in your repository: data access and logging.
Maybe wrap the current user in an abstraction that will get the user you need, but can be easily stubbed. Or you could wrap the repository in a decorator that does the logging for you.
Sorry this is not a direct answer to the question but, when tests are hard to write, there is usually a deeper underlying reason that you need to address.
I suggest you dont use the HttpContext from the repository, Make a own context class or a Interface wrapping the user-property.
Something like this:
public class MyContext
{
public MyContext(string username)
{
Username = username;
}
public string Username { get; private set; }
public static MyContext CreateFromHttpContext(HttpContext httpContext){
return new MyContext(HttpContext.Current.User.Identity.Name);
}
}
public class MyRep
{
private readonly VtContext _context;
public MyRep(MyContext context)
{
_context = context;
}
... other repository code...
}
then just create a MyContext in your test:
var rep = new MyRep(new MyContext("unittest"));

mvc5: Cannot access a disposed object. asp.net mvc5 using unity

im using vs 2013, mvc5 and ef6 + unity.mvc5:
my account controller class has this constructor:
public AccountController(UserManager<ApplicationUser> userManager)
{
this.UserManager = userManager;
}
and this is my unity config:
container.RegisterType(typeof(AccountController),
new InjectionConstructor(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>())));
when i try to register a new user i get this exception:
Cannot access a disposed object.
Object name: 'UserManager`1'.
on this line of code and register action:
var result = await UserManager.CreateAsync(user, model.Password);
when i remove unity and set dependecy resolver to default it works just fine.
i`v tried many unity configs but didnt work...
thanks alot for reading.
i found the solution, changed the unity config to this:
container.RegisterType<IUserStore<ApplicationUser>,
UserStore<ApplicationUser>>(new InjectionConstructor(new ApplicationDbContext()));
thanks all.
Do NOT create a parameterless constructor, (I can't vote it down as I don't have enough reputation), that answer totally avoids IoC and instead tries to build up the object by knowing the entire dependency hierarchy for the object, i.e. AccountController needs to know that it has a dependency on UserStore and it needs to know that Userstore has a dependency on UserContext. This is exactly what DI containers are there to avoid!
It is hard to provide you with an exact answer as there is a lot of your code missing.
One thing that looks odd to me is that you have an uppercase UserManger, that usually means that you are using it as a type, not referencing a local private variable. Can you show me the rest of the code?
Also, I would question why you are not referencing everything via Interfaces. That is by far the preferred way to set up proper DI.
I will try to knock up some test code that shows what I would do and then post this here, if you could answer those questions in the meantime that would be great.
Cheers Mike
Here is what I would do.
In your controller
public class HomeController : Controller
{
private IUserManager<ApplicationUser> userManager;
public HomeController(IUserManager<ApplicationUser> userManager)
{
this.userManager = userManager;
}
public ActionResult Index()
{
var user = "user";
var password = "password";
var result = userManager.CreateAsync(user, password);
return View();
}
}
Interface for UserManager
public interface IUserManager<T> where T : ApplicationUser
{
int CreateAsync(string user, string password);
}
Actual UserManager class
public class UserManager<T> : IUserManager<T> where T : ApplicationUser
{
private IUserStore<ApplicationUser> userStore;
public UserManager(IUserStore<ApplicationUser> userStore)
{
this.userStore = userStore;
}
public int CreateAsync(string user, string password)
{
return 0;
}
}
Interface for UserStore
public interface IUserStore<T> where T : ApplicationUser
{
}
Actual UserStore
public class UserStore<T> : IUserStore<T> where T : ApplicationUser
{
}
Unity configuration
container.RegisterType(typeof (IUserManager<>), typeof (UserManager<>));
container.RegisterType(typeof (IUserStore<>), typeof (UserStore<>));
Hope this helps.
There is obviously lots that is not the same as your app, i.e. not doing the method call async, not reading the password in from the model, etc. but it should give an idea of how to solve the problem that you outlined.
This solution will give you proper constructor dependency injection, which will allow you to have all of your configuration in one place (i.e. the container config) and it will give you interfaces in your constructors which will make it much easier for you to mock those dependencies in your unit tests.
Cheers Mike

MVC 5 IoC and Authentication

I am just about to start on a project, where I will be using MVC5. But as I want to use IoC and later reuse my user tables, and add custom stuff to it, I am finding it very hard to see how I can use the new Identity framework that came with MVC5.
I am more and more looking towards basic forms auth. What are your solutions?
My needs:
User repository/service must be injected
User repository must reside in the DAL
User repository must be able to support other technologies than EF
Authentication with OpenID and OAuth must be somewhat easy to implement
MUST BE SECURE
Should be reusable in other projects, eg. WPF
I have been looking for a long time for an answer, but everything I see is hardcoded in the controller.
How are you solving this? Are you writing most from scratch, or can you bind into something that will scale to other .NET platforms as WCF and WPF?
The below code is taken directly from the AccountController in the default ASP.NET MVC 5 Template.
The first thing it does is a Bastard Injection.
[Authorize]
public class AccountController : Controller
{
public AccountController()
: this(
new UserManager<ApplicationUser>(
new UserStore<ApplicationUser>(
new ApplicationDbContext())))
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
}
The accepted answer will go to the person, that shows me what they have done, that incorporates the above requirements
Since this is .NET, the standard approach to security is to authenticate at the application boundary, and convert the authentication information into an IPrincipal. MVC supports this out of the box.
If you need other information gained during authentication, you can gather that at in the Composition Root and use it to compose your services.
As an example, imagine that you need the authenticated user's email address in a lower layer. Any class that requires the user's email address can simply request it as a Concrete Dependency:
public class EmailThingy
{
private readonly string userEmail;
public EmailThingy(string userEmail)
{
if (userEmail == null)
throw new ArgumentNullException("userEmail");
this.userEmail = userEmail;
}
// other members go here...
}
In ASP.NET MVC, the Composition Root is IControllerFactory. IIRC, you can pull the authentication data from within the CreateController method and use it to compose your object graph.
These days, I use IPrincipal in the same way: I inject it as a dependency, instead of relying on the Thread.CurrentPrincipal Ambient Context, because it's easier to unit test when everything is consistently injected via Constructor Injection.
You might be interested to get a look at Thinktecture.IdentityServer.v2 https://github.com/thinktecture/Thinktecture.IdentityServer.v2. Many of your concerns are already implemented and encapsulated. If you don't find what you need you'll have to think about how to abstract all these concerns and implement it on your own.
I ended up deciding to implement the IUserStore, IUserStore, IUserPasswordStore, IUserLoginStore, to be able to move the UserRepository down into it's rightful place, the DataAccess Layer. But still get the Security Benifits of the Owin and new Identity Framework.
It's quite easy to implement, and doesn't take much to abstract it. Here is a taste of the UserStoreWrapper
namespace qubis.booking.WebApp.App_Code.Identity
{
public class UserServiceWrapper : IUserStore<ApplicationUserWrapper>,
IUserPasswordStore<ApplicationUserWrapper>,
IUserLoginStore<ApplicationUserWrapper>
{
public IUserRepository UserRepos { get; set; } // My own Interface.
public UserServiceWrapper(IUserRepository userRepo)
{
UserRepos = userRepo;
}
public async Task CreateAsync(ApplicationUserWrapper user)
{
UserRepos.Insert(user.RealUser);
}
public async Task<ApplicationUserWrapper> FindByIdAsync(string userId)
{
var appUser = UserRepos.FindByUserName(userId);
ApplicationUserWrapper wrappedUser;
if (appUser != null)
{
wrappedUser = new ApplicationUserWrapper(appUser);
}
else
wrappedUser = null;
return wrappedUser;
}
In the Account controller I Simply just ask for it to be injected:
public AccountController(UserManager<ApplicationUserWrapper> userManager)
{
UserManager = userManager;{ AllowOnlyAlphanumericUserNames = false };
}
And as I am using Ninject I just set it upin the kernel like so:
// <summary>
// Load your modules or register your services here!
// </summary>
// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUserStore<ApplicationUserWrapper>>().To<UserServiceWrapper>();
kernel.Bind<UserManager<ApplicationUserWrapper>>().ToSelf();
}
To see the Identity frameworks structure, please see this article. http://www.asp.net/identity/overview/extensibility/implementing-a-custom-mysql-aspnet-identity-storage-provider
If all you need is to inject custom UserStore implementation this article may help you
Basically you need to inject this (depends if you want to use roles, claims etc..):
Write a User class that implements the IUser interface
public class IdentityUser : IUser {
public IdentityUser(){...}
public IdentityUser(string userName) (){...}
public string Id { get; set; }
public string UserName { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
}
Write a User store class that implements the IUserStore, IUserClaimStore, IUserLoginStore, IUserRoleStore and IUserPasswordStore
public class UserStore : IUserStore<IdentityUser>,
IUserClaimStore<IdentityUser>,
IUserLoginStore<IdentityUser>,
IUserRoleStore<IdentityUser>,
IUserPasswordStore<IdentityUser> {
public UserStore(){...}
public Task CreateAsync(IdentityUser user){...}
public Task<IdentityUser> FindByIdAsync(string userId){...}
.. .
}

How to scope out Dbcontexts (to prevent singleton context for entire application)

I was wondering how do you scope out your Dbcontexts in Entity Framework so you don't use a single Dbcontext for your entire application. I am new to Entity Framework and have been reading tutorials, but they all used a single Dbcontext as an example, so EF is pretty much a blackbox for me right now.
Let's say for example I have 3 models:
Post
User
Comment
Each model is related to each other (A Post belongs to User, Comment belongs to User and Post). Do I make a Dbcontext for each one individually? But that wouldn't be correct since they are all related, or would I make a Dbcontext for each scenario that I need? For example, if I only need to query for Post and Comments and not user, that would be a PostCommentsContext. And then we would have a PostUserCommentContext...
The best solution would be to use a Unit of Work to wrap the Data Context, as well as managing the connection lifetime and allowing you to work with multiple Repositories (if you were so inclined to go down that path).
Summary of implementation:
Create an interface (IUnitOfWork) which exposes properties for your DbSet's, as well as a single method called Commit
Create an implementation (EntityFrameworkUnitOfWork), implementing as required. Commit simply calls SaveChanges on the base class (DbContext), and also provides a good hook-in for last minute logic.
Your controller accepts a IUnitOfWork, use DI (preferably) to resolve a EntityFrameworkUnitOfWork, with a HTTP-context scoped lifetime setting (StructureMap is good for this)
(optional, but recommended) create a Repository which also takes the IUnitOfWork, and work off that via your Controller.
HTH
EDIT - In Response to Comments
Oh, how can you do work that involves creating records in multiple models then? i.e., create a new user and a new post in the same transaction.
Given your using ASP.NET MVC, your controllers should accept an IUnitOfWork in their constructor.
Here's an example, based on what you asked
public SomeController : Controller
{
private IUnitOfWork _unitOfWork;
private IUserRepo _userRepo;
private IPostRepo _postRepo;
public SomeController(IUnitOfWork unitOfWork, IUserRepo userRepo, IPostRepo postRepo)
{
_unitOfWork = unitOfWork; // use DI to resolve EntityFrameworkUnitOfWork
_userRepo = userRepo;
_postRepo = postRepo;
}
[HttpPost]
public ActionResult CreateUserAndPost(User user, Post post)
{
// at this stage, a HTTP request has come in, been resolved to be this Controller
// your DI container would then see this Controller needs a IUnitOfWork, as well
// as two Repositories. DI smarts will resolve each dependency.
// The end result is a single DataContext (wrapped by UoW) shared by all Repos.
try
{
userRepo.Add(user);
postRepo.Add(post);
// nothing has been sent to DB yet, only two objects in EF graph set to EntityState.Added
_unitOfWork.Commit(); // two INSERT's pushed to DB
}
catch (Exception exc)
{
ModelState.AddError("UhOh", exc.ToString());
}
}
}
And one more question, what does the HTTP-context scoped lifetime do?
Objects in DI-talk have scope management settings that include per thread, per session, per http request, singleton, etc.
HTTP-context scoped is the recommended setting for web apps. It means "new up a context when a HTTP request comes in, and get rid of it when the request is finished".
Use 1 DbContext! That will make life easier for you. Don't worry about performance, data that isn't needed or queried won't be loaded and won't consume any resources.
public class UserContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Comment> Comments { get; set; }
}
For some scenarios you might want 2 or more contexts.
A context like the one above to hold all the front-end data needed for your application to work and another context for - as an example - to store reports generated from that front-end data, and which is only used in the back-end of you application.
I am experimenting with UnitofWork, here is what I have come up with...
First I created a IUnitofWork that only contains one method. Commit();
Then my dbContext looks like this
public class myContext : DbContext, IUnitOfWork
{
public DbSet<Users> Users { get; set; }
public DbSet<Addresses> Address { get; set; }
public void Save()
{
SaveChanges();
}
}
My repository classes take a UnitofWork in their ctors.
public class UserRepository : IRepository<Position>
{
private myContext _context;
public UserRepository (IUnitOfWork unitOfWork)
{
if (unitOfWork == null)
throw new ArgumentNullException("unitOfWork");
_context = unitOfWork as myContext;
}
/// other methods ///
}
Then the code in the controller would be something like this
_unitOfWork = new myContext();
_userDB = new UserRepository(_unitOfWork);
_addressDB = new AddressRepository(_unitOfWork);
_userDB.Add(newUser);
_addresesDB.Add(newAddress);
_unitOfWork.Save();
I have debugged and proved that no data is commited until the Save method of the _unitOfWork is called. Very cool stuff!!

Categories

Resources