Strongly Typed #User.Identity - asp.net-mvc-3

I customize IIdentity and IPrincipal adding a few more properties in IIdentity.
You can obtain a strongly typed instance #User.Identity for my custom class? Without having to make conversions in cast.
I thought of something like razor customize the View, but do not even know where to start.

You could try creating an extension method on IPrincipal
public static class PrincipalExtensions
{
public static MyIdentity GetMyIdentity (this IPrincipal principal)
{
return principal.Identity as MyIdentity;
}
}
and then get your identity by calling #User.GetMyIdentity()

You could create a new base type for your views and add to it a property or method that will do the casting. That way you can avoid doing it all the time in your views.

Related

Web Api 2 with OWIN OAuth Bearer tokens

I'm in the process of building a web api in visual studio 2013 and want to authenticate using OWIN middleware and bearer tokens. However I already have a database and don't want to use Microsoft's new Identity framework as the majority of tables and columns that it auto generates I simply don't need.
Can anyone point me in the right direction of how to apply this type of authentication without having to use the Microsoft Identity framework?
My suggestion would be to use the framework but extend it to use your objects and infrastructure. I am currently in the middle of doing this and landed on this question. Here's how I've tackled it so far:
Step 1: Your own CustomUserObject
Write/Use your own "ApplicationUser" object. In the template project, you want to modify the "IdentityModels" file. It has ApplicationUser object defined in there. Assuming you already have all the properties from your existing app, you will need to add GenerateUserIdentityAsync() method but change the type of the parameter to UserManager manager). After the change, your method signature looks like this:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<CustomUserObject> manager)
Step 2: Define your own IUserStore<> implementation
Add a new class CustomUserStore that implements IUserStore, like so:
public class CustomUserStore : IUserStore<CustomUserObject>
{
private readonly IUserManagerService _userManagerService;
public CustomUserStore(IUserManagerService userManagerService)
{
_userManagerService = userManagerService
}
//implementation code for all of the IUserStore methods here using
//userManagerService or your existing services/classes
}
I am using Unity to inject IUserManagementService's implementation above.
I have made use of the comprehensive UserManager class that comes with the Microsoft Identity framework but extended the framework to use my API for authentication and authorization. You could write your own UserManager but I found that it is pretty tedious and there is no reason why UserManager could work for most cases of Securing an app.
Step 3: Changes in the IdentityConfig.cs file
Change the class definition to make ApplicationUserManager class inherit from UserManager
You'll need to do the samething in the constructor of this class as well; i.e. have IUserStore. Modify the Create static method's first line to make use of the new store and a wrapper class that provides as a means to be a "DbContext" like so:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<UserManagementServiceWrapper>()));
//modify the relevant lines after this to suit your needs
...
}
My UserManagementServiceWrapper looks like this (please note that I'm not too happy that it inherits from a concrete UserManagementService class that provides the methods to connect to the service that provides user data, I'm still building this out):
public class UserManagementServiceWrapper : UserManagementService, IDisposable
{
public void Dispose()
{
throw new NotImplementedException();
}
}
Step 4: Change the ApplicationDbContext class to return a UserManagementServiceWrapper instance
public class ApplicationDbContext : UserManagementServiceWrapper
{
public static UserManagementServiceWrapper Create()
{
return new UserManagementServiceWrapper();
}
}
And that is pretty much it. You still have to write the implementation for CustomUserStore object but everything should work.
Please note this is not boilerplate code and no where near "code review ready", as I said, I'm still digging deeper into this and building it out to use custom stores, data access objects, services etc. I thought you'll get a good start with some of the things that took me a couple of hours to figure out. I will blog about this when I have a good solution.
Hope this helps.
I prob. dont understand the question entirely but it looks like you are trying to do without the whole owin pipeline?
If not then..
You need to implement few interfaces related to users and roles described as below.
http://www.asp.net/identity/overview/extensibility/overview-of-custom-storage-providers-for-aspnet-identity
Have a look at the following post from Scott Allen
http://odetocode.com/blogs/scott/archive/2013/11/25/asp-net-core-identity.aspx
This way you can use your own tables, DAL and services to create UserManager and RoleManager objects.
Edit: Samples over here should give you some pointers.
Edit2: Custom User Store Example.
IRepository is the object which takes care of CRUD.
public class CustomUserStore : IUserStore<User>,....
{
private readonly IRepository _repository;
public CustomUserStore(IRepository repository)
{
if (repository == null)
throw new ArgumentNullException("repository");
_repository = repository;
}
public Task CreateAsync(User user)
{
if (user == null) throw new ArgumentException("user");
_repository.User.Add(user);
return _repository.CommitAsync();
}
...

Constructor injection of a View Model instance used as an Action method parameter

When a view model is created you can populate the options (e.g. used in a dropdown list) into a setter property of the view model.
The problem is that when that view model is later passed as a parameter (by the framework!) into an action method, those property values has not become automagically
repopulated, so if you need to redisplay the form because of validation errors, you need to repopulate those options again.
One potential solution, which I am asking for specifically in this question, is how to make the MVC framework instantiate the view model with constructor injection, which would provide the view model constructor with an implementation of some kind of data access object (e.g. a repository) that can be used for retrieving the options when they are requested by the view (e.g. in the helper method "DropDownListFor") ?
I think the solution might have something to do with implementations of IModelBinderProvider or IModelBinder but after having experimented with these things from example code snippets here and there on the net, I am still looking for a completely working example, with downloadable executable code without any missing piece of how putting all things together.
If you are looking for some alternative discussion about how to populate a select list, e.g. with "Dependecy Lookup" instead of "Dependecy Injection" you may want to check out the following discussion:
Best way to populate SelectList for ViewModel on GET/POST
Best way to populate SelectList for ViewModel on GET/POST
Some days ago I wrote the following follow-up-question in that thread about the "Dependecy Injection" I am now looking for in this thread:
https://stackoverflow.com/a/8674525/310457
(which provides a code example about the problem I am looking for a solution of)
But instead of hoping that someone will find that old thread with a less specific title, I have created this new question with a more specific subject about what I am looking for.
And I will also provide a link from that thread into this new question for anyone that want to follow-up regarding this specific solution I am looking for.
I'm assuming you want to have your ViewModels automatically injected with something via their Constructor - for example some kind of configuration object that the View will use to determine what to show. I'm also assuming that this approach is causing a "No parameterless constructor defined for this object" error when MVC tries to automatically create and bind a model instance, from the arguments of your Controller Action. Let's also then assume that we will use a DI framework to inject the SiteConfig object into our Controllers automatically at runtime.
This means that the only problem we have to solve is how to get the injected object from our Controller into its Actions' ViewModels when they are automatically bound.
So let's define a base model for others to inherit from.
BaseViewModel
public class BaseViewModel
{
public ISiteConfig SiteConfig { get; set; }
public BaseViewModel(ISiteConfig siteConfig)
{
this.SiteConfig = siteConfig;
}
}
And now let's create a model that inherits from it.
IndexViewModel
public class IndexViewModel : BaseViewModel
{
public string SomeIndexProperty { get; set; }
public IndexViewModel (ISiteConfig siteConfig) : base(siteConfig) {}
}
And now let's define a Base Controller that our Controllers will inherit from.
BaseController
public abstract class BaseController : Controller
{
protected BaseController(ISiteConfig siteConfig)
{
_siteConfig = siteConfig;
}
private readonly ISiteConfig _siteConfig;
public ISiteConfig SiteConfig
{
get
{
return _siteConfig;
}
}
}
Now we define our actual controller.
HomeController
public HomeController: BaseController
{
public HomeController(ISiteConfig siteConfig): base(siteConfig) {}
}
Assuming we're using Ninject for DI, Ninject would be configured to automatically create the Controller and pass a concrete ISiteConfig object into its Constructor at runtime.
Now we add our Action to the Controller.
Index Action
public ActionResult Index(IndexViewModel model)
{
return View(model);
}
And so this is the point where without doing anything else, MVC will explode with a "Parameterless Constructor" error if you try to call the Index Action, because MVC can't find a ViewModel constructor that takes no arguments.
And so, the answer. We need to override the default ModelBinder.
BaseViewModelBinder
public class BaseViewModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
if (modelType == typeof(BaseViewModel) || modelType.IsSubclassOf(typeof(BaseViewModel)))
{
var baseControl = controllerContext.Controller as BaseController;
if (baseControl == null)
{
throw new Exception("The Controller must derive from BaseController");
}
var instance = Activator.CreateInstance(modelType, baseControl.SiteConfig);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => instance, modelType);
return instance;
}
else
{
return base.CreateModel(controllerContext, bindingContext, modelType);
}
}
}
And we need to set this as the default model binder in global.asax.cs :
protected void Application_Start()
{
...
ModelBinders.Binders.DefaultBinder = new BaseViewModelBinder();
}
That's all. As you can see, when you view the Index Action now, MVC will use our custom model binder. It will realise that the IndexViewModel derives from BaseViewModel, and so will attempt to spin up an IndexViewModel instance using the ISiteConfig it can find in the Action's Controller (because the Controller derives from BaseController).

ASP.NET MVC 3: Validating model when information external to the model is required

What's a good way to validate a model when information external to the model is required in order for the validation to take place? For example, consider the following model:
public class Rating {
public string Comment { get; set; }
public int RatingLevel { get; set; }
}
The system administrator can then set the RatingLevels for which a comment is required. These settings are available through a settings service.
So, in order to fully validate the model I need information external to it, in this case the settings service.
I've considered the following so far:
Inject the service into the model. The DefaultModelBinder uses System.Activator to create the object so it doesn't go through the normal dependency resolver and I can't inject the service into the model without creating a new model binder (besides which, that doesn't feel like the correct way to go about it).
Inject the service into an annotation. I'm not yet sure this is possible but will investigate further soon. It still feels clumsy.
Use a custom model binder. Apparently I can implement OnPropertyValidating to do custom property validation. This seems the most preferable so far though I'm not yet sure how to do it.
Which method, above or not, is best suited to this type of validation problem?
Option 1 doesn't fit. The only way it would work would be to pull in the dependency via the service locator anti-pattern.
Option 2 doesn't work. Although I couldn't see how this was possible because of the C# attribute requirements, it is possible. See the following for references:
Resolving IoC Container Services for Validation Attributes in ASP.NET MVC
NInjectDataAnnotationsModelValidatorProvider
Option 3: I didn't know about this earlier, but what appears to be a very powerful way to write validators is to use the ModelValidator class and a corresponding ModelValidatorProvider.
First, you create your custom ModelValidatorProvider:
public class CustomModelValidatorProvider : ModelValidatorProvider
{
public CustomModelValidatorProvider(/* Your dependencies */) {}
public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{
if (metadata.ModelType == typeof(YourModel))
{
yield return new YourModelValidator(...);
}
}
}
ASP.NET MVC's IDependencyResolver will attempt to resolve the above provider, so as long as it's registered with your IoC container you won't need to do anything else. And then the ModelValidator:
public class EntryRatingViewModelValidatorMvcAdapter : ModelValidator
{
public EntryRatingViewModelValidatorMvcAdapter(
ModelMetadata argMetadata,
ControllerContext argContext)
: base(argMetadata, argContext)
{
_validator = validator;
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
if (/* error condition */)
{
yield return new ModelValidationResult
{
MemberName = "Model.Member",
Message = "Rating is required."
};
}
}
}
As the provider is retrieved through the IDependencyResolver and the provider has full control over the returned ModelValidators I was easily able to inject the dependencies and perform necessary validation.
You could try fluent validation. It supports asp.net mvc and DI so you can inject external services into your validators.
Assuming that you want both client and server-side validation of the model based upon the values returned from the service, I would opt for 2., Inject the service into an annotation.
I give some sample code in my response to this question about adding validators to a model. The only additional step in your case is that you will need to inject your service into your class inheriting from DataAnnotationsModelValidatorProvider.
What about just simply using IValidateableObject and in that method determine if validation is appropriate or not and setting the errors there?
How do I use IValidatableObject?

MVC - Interface as Controller Action parameter

I want to pass one of a number of classes that implement an interface from my view back to my controller action. I use an ActionLink in my view passing the instance to my action, but it naturally fails because MVC cannot deal with interfaces via default model binding.
So :
<%=Html.ActionLink(flow.Source.Name, "Get", new {container=flow.Source})%>
is in a loop and each flow.Source conforms to IContainer.
public class Flow
{
public virtual IContainer Source { get; private set; }
}
public interface IContainer
{
//members here
}
public class File : IContainer
{}
public class Worksheet : IContainer
{}
Basically I want to call an action method :
public ActionResult Get(IContainer container)
{
// Do something
}
The reason being that I need to retrieve the state of the current container passed to my action method from the database. I use NHibernate and have entities mapped on a table per entity, so have one for File and one for Worksheet for example, so need to able to decide which data access class to use. Make sense? Probably not!
Can this be done without moving towards a base class Container? Can I stick with an interface being passed to my action method and resolve the subtype instance passed in place of the interface?
Any help with this would be gratefully appreciated.
An interface needs 'some' concrete implementation to reference when you would call your class. I think judging by your post you are aware of this : )
With that said there is 'kinda' of an approach handled here where you just create your own model binder that has to know about (or how) to map to and create a concrete type (either directly or by dependency injection)
ASP.NET MVC - Custom Model Binder on Interface Type

RhinoMocks: Correct way to mock property getter

I'm new to RhinoMocks, and trying to get a grasp on the syntax in addition to what is happening under the hood.
I have a user object, we'll call it User, which has a property called IsAdministrator. The value for IsAdministrator is evaluated via another class that checks the User's security permissions, and returns either true or false based on those permissions. I'm trying to mock this User class, and fake the return value for IsAdministrator in order to isolate some Unit Tests.
This is what I'm doing so far:
public void CreateSomethingIfUserHasAdminPermissions()
{
User user = _mocks.StrictMock<User>();
SetupResult.For(user.IsAdministrator).Return(true);
// do something with my User object
}
Now, I'm expecting that Rhino is going to 'fake' the call to the property getter, and just return true to me. Is this incorrect? Currently I'm getting an exception because of dependencies in the IsAdministrator property.
Can someone explain how I can achieve my goal here?
One quick note before I jump into this. Typically you want to avoid the use of a "Strict" mock because it makes for a brittle test. A strict mock will throw an exception if anything occurs that you do not explicitly tell Rhino will happen. Also I think you may be misunderstanding exactly what Rhino is doing when you make a call to create a mock. Think of it as a custom Object that has either been derived from, or implements the System.Type you defined. If you did it yourself it would look like this:
public class FakeUserType: User
{
//overriding code here
}
Since IsAdministrator is probably just a public property on the User type you can't override it in the inheriting type.
As far as your question is concerned there are multiple ways you could handle this. You could implement IsAdministrator as a virtual property on your user class as aaronjensen mentioned as follows:
public class User
{
public virtual Boolean IsAdministrator { get; set; }
}
This is an ok approach, but only if you plan on inheriting from your User class. Also if you wan't to fake other members on this class they would also have to be virtual, which is probably not the desired behavior.
Another way to accomplish this is through the use of interfaces. If it is truly the User class you are wanting to Mock then I would extract an interface from it. Your above example would look something like this:
public interface IUser
{
Boolean IsAdministrator { get; }
}
public class User : IUser
{
private UserSecurity _userSecurity = new UserSecurity();
public Boolean IsAdministrator
{
get { return _userSecurity.HasAccess("AdminPermissions"); }
}
}
public void CreateSomethingIfUserHasAdminPermissions()
{
IUser user = _mocks.StrictMock<IUser>();
SetupResult.For(user.IsAdministrator).Return(true);
// do something with my User object
}
You can get fancier if you want by using dependency injection and IOC but the basic principle is the same across the board. Typically you want your classes to depend on interfaces rather than concrete implementations anyway.
I hope this helps. I have been using RhinoMocks for a long time on a major project now so don't hesitate to ask me questions about TDD and mocking.
Make sure IsAdministrator is virtual.
Also, be sure you call _mocks.ReplayAll()
_mocks.ReplayAll() will do nothing. It is just because you use SetupResult.For() that does not count. Use Expect.Call() to be sure that your code do everything correct.

Resources