WEBAPI ActionContext Request.Properties.Add for store sensitive information - asp.net-mvc-4

I would like to pass information from the action filter (database) to the Action function.
Is it secure to use ActionContext Request.Properties.Add to store the data?
is there any chance that the information will be seen by the WEBAPI client or its safe as it safe to store information in the Cache\Session?
Is it a better way to do it?

The client will not see request properties unless you explicitly serialize them. They completely remain on the server side.
To answer your followup question here are two other ways to do it. There is no "Best" way per se. It all depends on how far you want the information to flow, and how generic you want your filter to be. My personal preference is using the controller object, but again it is just a preference.
For the sample here is a simple values controller and a POCO class:
[MyActionfilter]
public class ValuesController : ApiController
{
public string Foo { get; set; }
public User Get(User user)
{
if (Foo != null && user != null)
{
user.FamilyName = Foo;
}
return user;
}
}
public class User
{
public string FirstName { get; set; }
public string FamilyName { get; set; }
}
The action filter below is naively implementing access to the controller object or the method parameters. Note that it's up to you to either apply the filter sparingly or do type checks/dictionary checks.
public class MyActionfilter : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
controller = actionContext.ControllerContext.Controller;
// Not safe unless applied only to controllers deriving
// from ValuesController
((ValuesController)controller).Foo = "From filter";
// Not safe unless you know the user is on the signature
// of the action method.
actionContext.ActionArguments["user"] = new User()
{
FirstName = "From filter"
};
}
}

Related

How can I use my database tables etc Users table with ASP.NET Identity?

I have following tables:
Users, Groups, GroupUsers
I have my class like:
public class User
{
List<int> GroupIds;
}
I have a method in my Data Access Layer which returns a user after successful login with the list of all the group ids. How can I override or do something similar in identity to get information from that method?
I have searched the Internet a lot, watched YouTube tutorials, but no one is actually explaining it the way I need it. Can any one help?
First, use claims based security instead of role based: http://visualstudiomagazine.com/articles/2013/08/01/leveraging-claims-based-security-in-aspnet-45.aspx
I've also been retro-fitting an existing SQL based login system to work with identity management. Most of the work you're going to have to do lies within IdentityModel.cs. Specifically how you define ApplicationUser
public class ApplicationUser : IdentityUser<string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
I've overridden all 4 type parameters on the IdentityUser base class for my implementation, you may not need to do so, depends on how different your retrofit is from how Identity expects things to be.
The other main place you'll most likely have to customize things is within ApplicationDbContext where you'll have to set up where your user, group, and claims/role definitions reside with SQL.
I found these articles on typecastexception to be very useful:
http://typecastexception.com/post/2014/04/20/ASPNET-MVC-and-Identity-20-Understanding-the-Basics.aspx
http://typecastexception.com/post/2014/06/22/ASPNET-Identity-20-Customizing-Users-and-Roles.aspx
http://typecastexception.com/post/2014/04/20/ASPNET-Identity-20-Setting-Up-Account-Validation-and-Two-Factor-Authorization.aspx
http://typecastexception.com/post/2014/07/13/ASPNET-Identity-20-Extending-Identity-Models-and-Using-Integer-Keys-Instead-of-Strings.aspx
Overall there going to be a lot of trial and error in the process as you figure out what pieces of Identity you can utilize as is and where you need to plug in your own code.
Something else you may run into if your passwords aren't stored is having to provide your own implementation of PasswordHasher and plugging that in:
Asp.net Identity password hashing
I did' t get your question, if you want to override you have to mark the method virtual and inherit the class like this:
public class User
{
public virtual void YourMethod()
{
}
}
public class YourClass : User
{
public override void YourMethod()
{
}
}
If you want to separate the class to add some more mothods you can go like this:
partial class User
{
public static void YourMethod()
{
}
}
Create a UserInfo object
public class ApplicationUser : IdentityUser
{
public virtual UserInfo UserInfo { get; set; }
}
public class UserInfo : ComparableEntity
{
public string Email { get; set; }
public string FullName { get; set; }
public string KidName { get; set; }
public string MobilePhone { get; set; }
}
Then create a database context
public class DatabaseContext : IdentityDbContext<ApplicationUser>, IDatabaseContext
{
public IDbSet<UserInfo> UserInfos { get; set; }
}

How to implement custom role based authorization in ASP.Net MVC

I am working on a project where we are using Amazon SimpleDB as a data storage. In this application user can create roles at run time. While creating role, user can give Read/Write/Update permission for specific feature.
The code I have tried;
using System;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MyAuthorization : ActionFilterAttribute
{
public string Model { get; set; }
public string Action { get; set; }
public override void OnActionExecuting(HttpActionContext filterContext)
{
//My code will go here
base.OnActionExecuting(filterContext);
}
}
In Web API controller I have written as;
// GET api/values
[MyAuthorization(Action = "Edit", Model = "Rack")]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
Now in OnActionExecuting, I want to fetch Action and Model attributes which I have specified over action method in APIController.
How to handle it through code, since role names and rights are not known at design time.
I assume that each feature you will be implementing in a certain controller and each action method designates the type of operation you are performing (ex Read, Write etc).
If my assumption is correct, you may have to first extend the AuthorzeAttribute ASP.NET MVC framework like below.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public string Operation;
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
//Get the User Id from the session
// Get Role associated with the user (probably from database)
// get the permission associated with the role (like Read, write etc)
// Let assume the retrieved operations are in the form of list of strings
List<string> retrievedOperations =RetrieveRoleOperations(userId)
if (!retrievedOperations.Contains(Operation)
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
After creating this class, you have to specify the extended authorize filter in required action methods like below.
Class MyFeatureController:Controller
{
[MyCustomAuthorize(Operation="Read")]
public ActionResult MyReadMethod()
{
//
}
}
I hope this will solve your problem.

Can I programmatically determine the database "context" to use based on user credentials?

This is a followup to the question here, where the answer seems to refer to an overly-complicated and overly-specific (EF, which I'm not using - not even using an ORM).
There has to be a more straightforward way around this common scenario than the smoke, mirrors, and sorcery hinted at in that answer.
Note: I encased "context" in parenthesis because I'm not using EF, so it is not a literal "dbcontext" that I'm talking about here.
So I got to wondering: Could I set a global variable for each session when the user is authenticated and authorized?
e.g., when the user is authenticated/authorized, I would know which database context/contents should be served up to him.
So it seems I could set a value in Global.asax.cs' Application_Start() method and then either alter the RepositoriesInstaller (implementing IWindsorInstaller) class to conditionally register different concrete Repositories based on the user and what data he should have OR place conditional code in the concrete Repository itself to use this or that database instance.
Is this feasible? Is one way (altering the RepositoriesInstaller / altering the concrete Repositories class) preferred?
Have a look at this answer which will show you how to resolve the correct repository based on a key or value.
If you want to store it with the authorized user, you need to simple serialize the data and store it on the authenticated cookie:
Create a Model to represent the logged in information:
public class AuthenticatedMember
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int SiteNumber { get; set; }
}
Do something like a login in your controller:
var authenticatedMember = MembershipManager.ValidateLogin(model.Email, model.Password);
var cookie = FormsAuthentication.GetAuthCookie(authenticatedMember.Id.ToString(), false);
var ticket = FormsAuthentication.Decrypt(cookie.Value);
var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, authenticatedMember.ToJson(), ticket.CookiePath);
cookie.Value = FormsAuthentication.Encrypt(newTicket);
Response.Cookies.Add(cookie);
Then use a model binder to deserialize the AuthenticatedMember when you require:
public class AuthenticatedMemberModelBinder : IModelBinder
{
#region IModelBinder Members
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.Model != null)
{
throw new InvalidOperationException("Cannot update instances");
}
if (controllerContext.RequestContext.HttpContext.Request.IsAuthenticated)
{
var cookie = controllerContext
.RequestContext
.HttpContext
.Request
.Cookies[FormsAuthentication.FormsCookieName];
if (null == cookie)
return null;
var decrypted = FormsAuthentication.Decrypt(cookie.Value);
if (!string.IsNullOrEmpty(decrypted.UserData))
{
return JsonConvert.DeserializeObject<AuthenticatedMember>(decrypted.UserData);
}
}
return null;
}
#endregion
}

Why does ASP.NET MVC assumes that view will have matching input and output types?

ASP.NET MVC (or rather Html.Helpers and base page implementation) assumes that there will be one type for both rendering and posting (namely Model).
This is a violation of ISP, isn't it?
I am tempted to derive my Edit views (those that have different render-data, and post-data) from a custom EditPageBaseView<TViewModel, TFormData>.
The problem is I want my validation and post work against FormData instance (stored inside ViewModel), but MVC assumes that entire ViewModel will be POSTed back.
Is there an OOB way to facilitate that? (I didn't find one if there is).
Is it a bad idea (in concept) to have separate data types for different operations exposed by a service (a view in this case).
I tend to follow the CQRS model when constructing my view models. All rendering is done with ViewModel classes and all posting back is done with Command classes. Here's a contrived example. Let's say we have a View with a small form for creating users.
The ViewModel and Command classes looks like this:
public abstract class ViewModel {}
public abstract class Command: ViewModel
public class CreateUserViewModel : ViewModel
{
public string Username { get; set; }
public string Password { get; set; }
public string PasswordConfirm { get; set; }
}
public class CreateUserCommand : Command
{
public string Username { get; set; }
public string Password { get; set; }
public string PasswordConfirm { get; set; }
}
The UserController creates a CreateUserViewModel as the model for the Get request and expects a CreateUserCommand for the Post request:
public ActionResult CreateUser()
{
// this should be created by a factory of some sort that is injected in
var model = new CreateUserViewModel();
return View(model);
}
[HttpPost]
public ActionResult CreateUser(CreateUserCommand command)
{
// validate and then save the user, create new CreateUserViewModel and re-display the view if validation fails
}
Model binding takes care of ensuring that the properties of the Posted CreateUserCommand are populated properly, even though the Get View is bound to a CreateUserViewModel.
They don't have to match, but they do match by default.
If you don't want them to match, you can specify a different model in your Form or ActionLink:
Example of a Mismatch using Razor and C#:
Index.chtml:
#model FirstModel
<div>
#using (Html.BeginForm("Action", "ControllerName", new { ParameterName = new SecondModel { First = "First", Second = "Second" } }, FormMethod.Post)) {
<input type="submit" value="Submit Button" />
}
</div>
The Controller:
public class ControllerName : Controller {
public ActionResult Index() {
return View(new FirstModel());
}
public ActionResult Action(SecondModel ParameterName) {
return View() // Where to now?
}

Domain Driven Design in a Workflow-enabled MVC Application - Design Decision

I'm building an N-Tier MVC 4 Application that implements the Repository and UnitOfWork patterns as well as Domain Driven Design using an abstracted CommandProcessor layer that validates and executes my CommandModels.
I'm beginning to learn Workflow Foundation now and have added a workflow project that handles user registration. At the end of the workflow if everything went through, the workflow will execute the ApproveMembership CodeActivity:
public sealed class ApproveMembership : CodeActivity
{
[RequiredArgument]
public InArgument<string> UserEmail { get; set; }
protected override void Execute(CodeActivityContext context)
{
IDatabaseFactory databaseFactory = new DatabaseFactory();
IUnitOfWork unitOfWork = new UnitOfWork(databaseFactory);
IUserRepository userRepository = new UserRepository(databaseFactory);
string userEmail = UserEmail.Get(context);
User user = userRepository.Get(u => u.Email == userEmail);
if (user != null)
{
user.Activated = true;
userRepository.Update(user);
unitOfWork.Commit();
}
}
}
There is also a similar RemoveMembership activity that deletes the user after a certain time if he never validates.
My question is, does it make sense to handle this right inside my workflow? Or is the better approach to use Dependency Injection in the workflow to get a CommandBus that will handle processing 2 new, almost identical command models that I will have to create, along with Validation and Submission handlers for them? This is how it's done in my MVC AccountController.
public class DeleteUserCommand : ICommand
{
public int UserId { get; set; }
}
public class ApproveUserCommand : ICommand
{
public int UserId { get; set; }
}
public sealed class RemoveMembership : CodeActivity
{
public InArgument<string> UserEmail { get; set; }
private readonly ICommandBus commandBus;
private readonly IUserRepository userRepository;
public RemoveMembership(ICommandBus commandBus, IUserRepository userRepository)
{
this.commandBus = commandBus;
this.userRepository = userRepository;
}
protected override void Execute(CodeActivityContext context)
{
string userEmail = UserEmail.Get(context);
User user = userRepository.Get(u => u.Email == userEmail);
if (user != null)
{
var command = new DeleteUserCommand
{
UserId = user.UserId
};
IEnumerable<ValidationResult> errors = commandBus.Validate(command);
if (!errors.Any())
{
commandBus.Submit(command);
}
}
}
}
Obviously it's a lot more code but is it good design?
I feel like I answered me own question writing this and I'm thinking the answer is YES. But would still like to hear a professional opinion.
My question is, does it make sense to handle this right inside my
workflow?
I would encapsulate the code that you have inside the CodeActivity into an application service and have the workflow reference that application service:
class UserApplicationService
{
public void ApproveMembership(string userEmail)
{
var user = userRepository.Get(u => u.Email == userEmail);
if (user != null)
{
user.Activated = true;
userRepository.Update(user);
}
}
}
public sealed class ApproveMembership : CodeActivity
{
[RequiredArgument]
public InArgument<string> UserEmail { get; set; }
protected override void Execute(CodeActivityContext context)
{
var userEmail = UserEmail.Get(context);
this.userService.ApproveMembership(userEmail);
}
}
The motivation for this is that WWF is an infrastructural component in your architecture and it serves well to decouple infrastructure from domain logic. WWF could be replaced by something like NServiceBus in which you'd reference the same application service. Some would say this is a case of YAGNI but I think that separating infrastructure for domain code is very beneficial both in terms of code quality and the ability to reason about the domain.
I would also recommend that you push the unit of work code into the infrastructure as much as possible, so that application services don't have to call Commit explicitly.
Or is the better approach to use Dependency Injection in the workflow
to get a CommandBus that will handle processing 2 new, almost
identical command models that I will have to create, along with
Validation and Submission handlers for them?
This seems more in line with my suggestion, however based on your code sample, I'd recommend going a step further and extracting most more of the logic inside the CodeActivity into an application service, or structure the application in such a way that you can dispatch a command without needed access to a repository.