I've got an architecture issue that I'm hoping someone can be of assistance to guide me in a more ideal strategy. The way I've been forced to do this reeks of "code smell".
I've got two different kinds of "Roles". I've got the built in Identity Roles, and I've got a custom set of roles (User Group Roles). I store these User Group Roles in a database, essentially a relationship between a user id, a usergroup role id, and a usergroup id. I'm using Ninject for dependency injection of my UserGroupService that handles all the CRUD operations of assigning users with certain usergroup roles to usergroups.
My first plan of attack was to create a custom authorization attribute that I could place on actions, similar to the Identity [Authorize(Role="")] attribute. I did not have any luck with this because I cannot inject a service into an attribute class (needs a parameterless constructor).
After that didn't work, my second plan of attack was to write an extension method for IPrincipal, essentially mimicking User.IsInRole("") with User.IsInUserGroupRole(""). This didn't work because I cannot inject a service into a static class.
Currently I am stuck including some booleans in the model of every view that has role based logic involved. So for instance:
public ActionResult Navigation()
{
var isSystemAdmin = User.IsInRole("Administrator");
var isUserGroupAdmin = _userGroupService.IsUserGroupAdmin(User.Identity.GetUserId()) && !isSystemAdmin;
var isGeneralUser = !isSystemAdmin && !isUserGroupAdmin;
var model = new NavigationViewModel
{
IsSystemAdmin = isSystemAdmin,
IsUserGroupAdmin = isUserGroupAdmin,
IsGeneralUser = isGeneralUser
};
return PartialView("_Navigation", model);
}
The issue here is that I have to do this any time I want to determine what kind of roles the user is currently in. It works, but it smells.
Am I missing something here? I think the most ideal option would be the extension method strategy of being able to call it right off of User, but cannot seem to make that work.
Constructor DI is not the only way to get access to a dependency.
Each IOC has a way of resolving a dependency, all you need is a reference to the IOC container. So, even if your attribute requires a parameterless constructor you could still resolve the dependency manually.
Something like this should help :
http://www.c-sharpcorner.com/UploadFile/47fc0a/resolving-dependency-using-ninject/
Is it a great way to use your IOC this way? Probably not but it sure beats what you're doing now.
Related
I have been implementing Jhipster at my work and loving it. I was asked to implement a security validation that one user should not be allowed to edit the entity created by other user. For this I need two things:
First, in all entities, add a ManytoOne relation with User entity.
In Backend put a validation in controller while updating the entity to check if current logged in user is same as what is stored in DB. In front end also same logic to show/hide edit button.
I have done a POC for this and it works but is little ugly, check the code:
public ResponseEntity<Entry> updateEntry(#RequestBody Entry entry) throws URISyntaxException {
log.debug("REST request to update Entry : {}", entry);
if (entry.getId() == null) {
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
}
//here is my logic
Optional<Entry> entry_db = entryRepository.findOneWithEagerRelationships(entry.getId());
if(!entry_db.get().getUser().getId().equals(userService.getUserWithAuthorities().get().getId())) {
//throw someexception
}
//
Entry result = entryRepository.save(entry);
return ResponseEntity.ok()
.headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, entry.getId().toString()))
.body(result);
}
Is there any better or OOTB way of doing this??? may be something in spring security i am not aware of??
Thanks for help!!
This is a job for Spring Security Expression-Based Access Control, in particular you could annotate your method with #PreFilter and a custom PermissionEvaluator you would implement with similar logic as in your POC. The PermissionEvaluator could be generic and applied to several entity types if you define an Owned interface that models the ownership with a method like User getOwner() and that all your entity classes would implement.
See https://docs.spring.io/spring-security/site/docs/current/reference/html5/#el-access
The annotated method should be in a service rather than in a resource controller.
Also, UserService alone will not help you in finding the current authenticated user, you should use JHipster's SecurityUtils first and then ÙserService if you need more data about it.
In my MVC application I have Player and Coach objects, and a user can be one or the other. I also have Team objects and what I want to know is how I prevent a user who is in a list of Players or is the Coach of a Team gaining access to a route like /Teams/Details/2 where 2 is the id of a team other than that which he/she is part of.
Thanks in advance!
Since you want to restrict an id that they aren't a part of, this seems like a situation where you can Inherit from the AuthorizeAttribute and provide your implementation for AuthorizeCore
Your implementation could check their role/team id and decide what to do / redirect.
public class TeamAuthorize : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return UserIsInTeam(httpContext); //whatever code you are using to check if the team id is right
}
}
You can now apply it like any other attribute.
[TeamAuthorize]
The very simplest solution would be to change the URLs from using IDs to random GUIDs. You would almost eliminate the chance of someone guessing another valid value. Of course, this is not secure by definition (mostly because someone could get the other URL from history or another source), but in some scenarios this is enough.
A better solution is to create a new attribute based on IActionFilter interface that implements OnActionExecuting method and checks the ID by using this.ControllerContext.HttpContext.User.Identity.Name and this.RouteData.Values["id"]. You will then apply this attribute to your controller methods.
In our current system we implemented row level security in controller methods by just adding the code that verifies the user permissions as the first line in each method. The checking code is the same as with the attribute and it requires the same amount of code to add. This approach has one additional benefit - it is easier to implement scenarios like where a coach would be able to see the details of other teams but not modify them (we have one action and view for both reading and updating depending on permissions).
You would also use the last approach if you need to go to the database to check the permissions and you are using IoC frameworks such as Ninject with constructor based injection - since you will not have access to those values in the attribute.
Thank you for any thoughts.
I am trying to learn about MVC architecture, and working on a small project which is as much about me learning the tool than the requirements of the project.
I need to figure out what constitutes good, acceptable, and poor practice, and why. I fully understand there will be no specific right answer, but there must be architectures which fit into any of the spectrum of good -> terrible. While in a sense more than a single question, I hope the logical flow of good design practice means they all relate back to a single encapsulating answer.
I m using Code First Membership provider by Darko Pečnik
User implements an interface IUser which hides many of the properties such as Primary key and password, which should be accessed/altered via the methods belonging to Membership class. It also uses a getter and setter for an array of strings rather than the User.Roles Collection via:
public virtual String[] RoleNames
{
set
{
this.Roles = (ICollection<Role>)value.Select(r =>
new Role { RoleName = r }).ToList();
Question 1.) I suspect this property might be bad practice, but am unsure of exactly why. Would these be better as methods GetRoleNames and SetRoleNames, or would the Icollection itself be better included in the IUser interface?
Two seperate viewModels exist which are mapped from IUser using AutoMapper. These models relate to whether the user is registering/updating details about them-self, or being registered/updated by a website administrator.
one viewModel contains an IEnumerable for roles and departments. these properties are currently being mapped via automapper:
internal class RoleStringArrayToSelectListResolver
: ValueResolver<String[], IEnumerable<SelectListItem>>
{
protected override IEnumerable<SelectListItem> ResolveCore(String[] source)
{
return Roles.GetAllRoles().Select(x => new SelectListItem
{
Value = x,
Text = StringExtensions.ToSeparatedWords(x),
Selected = source.Contains(x)
Question 2.) Is autoMapper an acceptable place to put such logic, and if not where should it go?
Question 3.) After postback, business logic is validated via repository methods createUser and updateUser. Would it be optimal for these methods to accept an IUser instance as an argument, or preferable for a couple of overloads accepting the various viewModels as arguments, and if so why?
Thank you very much for any thought ideas and helping my understanding.
Why have you created an IUser interface? I haven't seen any reasons in your question explaining why it is useful. Do you anticipate swapping out different implementations of it? Or does 1 project depend on its properties, without having access to the concrete User class?
Question 1.) I suspect this property might be bad practice, but am
unsure of exactly why. Would these be better as methods GetRoleNames
and SetRoleNames, or would the Icollection itself be better included
in the IUser interface?
It seems to me that what you want to be able to do is access and manipulate Role items in your ICollection Roles property using role name strings only. You could leave the class alone (don't create a property or a method), and just implement this as an extension method:
public static class UserExtensions
{
public static string[] GetRoleNames(this User user)
{
return user.Roles.Select(r => r.Name).ToArray();
}
public static void SetRoleNames(this User user, params string[] roleNames)
{
user.Roles = roleNames.Select(s => new Role { RoleName = s }).ToList();
}
}
With this, you can get and set role names accordingly. The extension method just works against what is already defined in the User class, without cluttering it with overloads. The extension method could just as easily be written against the IUser interface instead of the concrete User class. You would just write this IUser user instead of this User user.
var user = MethodToGetOrCreateUser();
string[] roleNames = user.GetRoleNames();
if (!roleNames.Any())
user.SetRoleNames("StandardUser", "SomeOtherRole");
Question 2.) Is autoMapper an acceptable place to put such logic, and
if not where should it go?
I think I see what you are doing: You have a string[] of role names (probably from your User.GetRoleNames property/method). Given that string array, you want to create an IEnumerable of SelectListItems. There should be a SelectListItem for every role, but only the ones which match a string in your array should be selected. Since your client code does not have all of the Role names, you gave that responsibility to the value resolver. Your client code may then look something like this:
var user = MethodToGetOrCreateUser();
string[] roleNames = user.GetRoleNames();
var rolesMenu = Mapper.Map<IEnumerable<SelectListItem>>(roleNames);
In essence you are making automapper "smart" enough to know how to get all of the other role names that that user is not in. Automapper shouldn't be this smart; having any kind of automapper resolver access a data store is generally not a good idea, and you should avoid it if possible. Otherwise you end up with static references to access data storage. Something like this could go in your controller, and is clearer:
// this should actually go in Application_Start
Mapper.CreateMap<IEnumerable<Role>, IEnumerable<SelectListItem>>()
.ForMember(d => d.Value, o => o.MapFrom(s => s.RoleName))
.ForMember(d => d.Text, o => o.MapFrom(s => s.RoleName.ToSeparatedWords()))
;
// create your menu with all roles
var rolesMenu = Mapper.Map<IEnumerable<SelectListItem>>(Roles.GetAllRoles());
// select only the roles that the user is in
var user = MethodToGetOrCreateUser();
user.GetRoleNames().ToList().ForEach(r =>
{
var match = rolesMenu.SingleOrDefault(i => i.Value == r);
if (match != null) match.Selected = true;
});
I have found that you can avoid ValueResolver classes altogether. Anything you can do with a ValueResolver class you can also do with the lambda overload .ResolveUsing().
Question 3.) After postback, business logic is validated via
repository methods createUser and updateUser. Would it be optimal for
these methods to accept an IUser instance as an argument, or
preferable for a couple of overloads accepting the various viewModels
as arguments, and if so why?
Your business layer should never accept viewmodels as arguments. They are models for the view, not for the business. Think of the business code as your MVC project's client. If you ever moved your business code outside of the MVC project, and you had business code that took ViewModels as arguments, the code would not compile. Why? Because the viewmodels are in the MVC project, and the MVC project takes a dependency on the business project -- not vice versa.
Background : We are using MVC4 and using WIF for Claims/Authorization. We are using Moq/MvcContrib for Mockup Objects. I have looked here and created the MockIdentity and MockPrincipal Objects - do I need them?
Goal : I have a controller class that has a class level attribute that only allows users with 'Manager' claim to access the actions. I want to create mock users and test to see if anyone that doesn't have 'Manager' claim can access the actions or not.
I get the mock concept but I have only dealt with the data objects mocking and having a tough time figuring out what plugins/classes/methods/setups I need in place to do what I need to do.
Thanks in advance.
I want to create mock users and test to see if anyone that doesn't have 'Manager' claim can access the actions or not.
No, you don't. You just want to pass users to that attribute you wrote and test that sets the filterContext.Result correctly. That's it. You don't need to test that System.Web.Mvc works. Single unit under test!
Presumably your attribute is an AuthorizeAttribute, correct? So you need to test OnAuthorization(AuthorizationContext).
Disclaimer: I haven't used moq in a while, but your code would presumably look generally like this:
var user = new Mock<IPrincipal>();
user.Setup(/* whatever you need to look at */);
var authContext = new Mock<AuthorizationContext>();
authContext.Setup(ac => ac.HttpContext.User).Returns(user);
var myAttribute = new RequireManagerAttribute();
myAttribute.OnAuthorization(authContext);
authContext.VerifySet(ac => ac.Result = /* whatever you expect */);
In the real world, Controllers can potentially need to use data from a variety of database tables and other data stores. For example:
[Authorize]
public class MembersController : Controller
{
ICourseRepository repCourse;
IUserCourseRepository repUserCourse;
IMember member;
public MembersController(ICourseRepository repCourse, IUserCourseRepository repUserCourse, IMember member)
{
this.repCourse = repCourse;
this.repUserCourse = repUserCourse;
this.member = member;
}
So:
Should I use a repository for each table?
I guess this is where the concept of agregates comes into play? Should I have one Repository per aggregate?
Do I just add as many Repositories as I need to the constructor of the Controller?
Is this a sign that my design is wrong?
NOTE:
The IMember interface essentially represents a helper object that puts a nice face on the Membership provider. Ie, it puts all the code in one place. For example:
Guid userId;
public Guid UserId
{
get
{
if (userId == null)
{
try
{
userId = (Guid) Membership.GetUser().ProviderUserKey;
}
catch { }
}
return userId;
}
}
One problem with that is surely caching this kind of output. I can feel another question coming on.
EDIT:
I'm using Ninject for DI and am pretty sold on the whole DI, DDD and TDD thing. Well, sort of. I also try to be a pragmatist...
1. Should I use a repository for each table?
Probably not. If you have a repository per table, you are essentially doing Active Record. I also personally prefer to avoid calling these classes "Repository" because of the confusion that can occur between Domain Driven Design's concept of a "Repository" and the class-per-table "Repository" that seems to have become commonly used with Linq2SQL, SubSonic, etc. and many MVC tutorials.
2. I guess this is where the concept of agregates comes into play? Should I have one Repository per aggregate?
Yes and yes. If you are going to go this route.
'3.' Do I just add as many Repositories as I need to the constructor of the Controller?
I don't let my controllers touch my repositories directly. And I don't let my Views touch my domain classes directly, either.
Instead, my controllers have Query classes that are responsible for returning View Models. The Query classes reference whatever repositories (or other sources of data) they need to compile the View Model.
Well #awrigley, here is my advise:
Q: Should I use a repository for each table?
A: No, as you mentioned on question 2. use a repository per aggregate and perform the operations on aggregate root only.
Q: Do I just add as many Repositories as I need to the constructor of the Controller?
A: I guess you´re using IoC and constructor-injection, well, in this case, make sure you only pass real dependencies. this post may help you decide on this topic.
(pst! that empty catch is not a nice thing!!) ;)
Cheers!
This all depends on how "Domain Driven Design" your going to be. Do you know what an Aggregate Root is? Most of the time a generically typed repository that can do all your basic CRUD will suffice. Its only when you start having thick models with context and boundaries that this starts to matter.