I'm not sure if I am approaching this the right way; looking for some input from the community.
I'm using the following pluggins:
sfDoctrineGuardPluggin //for user management
sfForkedDoctrineGuardApplyPluggin //for registration of new users
What I'm trying to achieve:
I'd like to allow my registered users to register child-users. To do this, the child-user's that they create must inherit a couple of the parents attributes (their corporate_id, employer_type, etc... in child-user's profile at bind time). Setting these attributes has been challenging, as from what I can surmise from my reasearch, the sfApplyApply form does not have setters that can be overridden.
As an alternative, I attempted to create a whole new "user" module which uses the sf_guard_user table schema. This worked somewhat, but it lost the features found in the registration pluggin (email confirmation) and it was not salting the password or something because I was never able to login a user created this way - which always produced an error saying the username or password were incorrect.
So the question is, what's the best approach to achieve my desired result?
In your action:
public function executeNew(sfWebRequest $request)
{
$this->form = new sfApplyChildApplyForm();
}
In the plugin forms, create a form called sfApplyChildApplyForm modeled after sfApplyApplyForm.
That's it.
Related
We have a ViewModel for "create" and one for "edit." The edit inherits from create so that we're sharing common fields. We are then using an #Html.EditorForModel("User") that uses the "create" as its model.
This is for editing users, so I need the password field to be required on create, but not required on delete. Thus, the create VM has Password with [Required] decorating it, while the edit VM has password property with no decoration, and is also declared with new (public new string Password {get;set;}).
This is almost exactly similar to this question:
MVC4 Conditional Required Annotation
For my situation, it's still requiring the field I believe due to the EditorTemplate using the create object as its model instead of the edit. I tried changing it from editorformodel to:
#Html.EditorFor(model=>model, "User")
in hopes that because edit is actually a "create" due to inheritance that it would work, but it'still barking at me for not providing the required field when I post.
Is there a way to accomplish what I'm attempting, or are my options to either remove the required and handle it server-side, or split the editor template into two templates?
You can create a custom attribute to drive your check on whether the password is required or not. When the submission happens to the server your custom attribute can check to see if the you are dealing with an Update or and Insert and then invalidate the model if it needs to.
Here are some resources on creating custom attributes and custom attributes with unobstrusive jquery validation
Happy Coding!!
Just curious what would be the best way to do this?
used to using
if (User.IsInRole("Administrator"))
with an older program of mine,
Using the new Kendo templete( new to me ) for MVC4-VS2012 Projects it created everything w/o simplemembership, so i wrote my own login system with help of some youtube videos and documentations.
It is very flexible and works, just curious on how I can check if a user is in a Roll Via A view ( like if (User.IsInRole("Administrator")) ) would have done. And or the best way to do so ( possibly in controller )
You can continue to use User.IsInRole(""), you simply need to set HttpContext.User with the correct principal that has a list of roles.
You can create your own Authorization Attribute that would take care of this:
var websiteRoles = userRepo.GetRoles(HttpContext.User.Identity.Name);
var identity = filterContext.HttpContext.User.Identity as FormsIdentity;
filterContext.HttpContext.User = new System.Security.Principal.GenericPrincipal(identity, websiteRoles.ToArray());
Follow up:
Your GetRoles() method can be implemented any way you like, you simply need to have a list of roles that the user belongs to. You will use this list to create the Principal object to set the User to.
Using this approach will allow you to use User.IsInRole()
In certain Controller I have CRUD methods. In order to access these methods user needs to be logged in. This is why I used [Authorize] attribute for this controller. Now I need additional attribute which would check if item that user wants to view/delete/update belongs to him.
Is it possible and recommended to do this with attribute or you would suggest using check methods inside each method? If you suggest using attribute, could you please provide me some links/instructions?
EDIT:
Ofcourse, if attribute returns false than I don't want to redirect user to login page but show him an error message...
It can be done with a custom Authorize attribute, but it's much cleaner to put the logic inside your controller methods.
The attribute is related to the action being called (the controller class method). On that basis any attribute relating to the user's ownership of the object being manipulated (from your Model) should really be on the entity/class that the user is attempting to manipulate. You'll probably find it easier to validate the user within the Model method rather than using an attribute to achieve this.
In my opinion it is possible, just google for 'Custom Authorize Attribute'.
But maybe it is better to query your database with something like this:
ContextOrSession.Query<Something>.Where(Something.Groups.Intersect(User.Groups).Count>0)
I am creating my own website and blog and I want for first time just me in database (my name and password) and maybe later some registration for others but first log in just for me and administration with authorization. I don´t want to use Membership from MS. I want try to create my own from start so I am looking for guide for beginners but I found big guides with roles, rights. I want just small example with check username, password in database with log on data.
Thanks for help
Libor
Even if you don't want to use the membership and role provider data store you can still utilize the authentication. Trust me, it's a lot easier than building your own. Here's how it works:
We'll say you already have your user storage setup for retrieving the username and their password. For the sake of simplicity I'm going to pretend you have a static class called DataLayer that contains your data retrieval methods for pulling info from the database (or whatever storage you use).
First you need a way to let the user log in. So set up a page with username and password fields. Then in the action method that the page posts to set up a quick if statement:
if (DataLayer.UserExists(userModel.Username))
{
User userFromDB = DataLayer.GetUser(userModel.Username);
if (userFromDB.Password == userModel.Password)
{
FormsAuthentication.SetAuthCookie(userFromDB.Username, checkBoxRememberMe.Checked);
//Use userFromDB as the username to authenticate because it will
//preserve capitalization of their username the way they entered it
//into the database; that way, if they registered as "Bob" but they
//type in "bob" in the login field, they will still be authenticated
//as "Bob" so their comments on your blogs will show their name
//the way they intended it to.
return "Successfully logged in!";
}
}
return "Invalid username or password.";
Now that they are authenticated you can just use Page.User.Identity.IsAuthenticated in your code to find out if they are logged in. LIke this:
if (User.Identity.IsAuthenticated)
{
DataLayer.PostBlogComment(User.Identity.Name, commentBody);
//Then in your controller that renders blog comments you would obviously
//have some logic to get the user from storage by the username, then pull
//their avatar and any other useful information to display along side the
//blog comment. This is just an example.
}
In addition, you can lock out entire action methods or even whole controllers to users that are authenticated through the forms authentication provider. All you have to do is add tags like these to your action methods/controllers:
[Authorize]
public ActionResult SomeActionMethod()
{
return View();
}
The [Authorize] attribute will prevent users that are not logged in from accessing that action method and it will redirect them to your login page. You can use this same attribute to filter out roles if you are using the built in roles provider.
[Authorize(Roles="Admin, SalesReps")]
public ActionResult SomeActionMethod()
{
return View();
}
These attributes can also be added above the controller class to apply it's logic to the entire controller.
EDIT: To log a user out all you need to do is call FormsAuthentication.SignOut();
Hey #Bibo, good for not choosing the Membership providers. I think a UserService or similar which provides methods for creating, authenticating users and some few more methods should be enough. As a suggestion, use password hashing and a password salt for the user´s password. Here is a good link to look at. Also have a look at this answer I gave some time ago.
Good luck!
EDIT: The rememberMe parameter should be named keepMeSignedIn instead.
This article on forms authentication gives you loads of info for creating your own simple security system, especially the bit about FormsAuthenticationTicket.
http://support.microsoft.com/kb/301240
I'm currently developing a menu for my application that should be able to display only the controllers that the current user can access (requestmap defined in the database).
How can I check if the current user has access to a specific controller and action?
To check roles in view :
Spring security plugin provides ifAllGranted, ifAnyGranted, ifNoneGranted etc., tags to check roles
For example, to check Admin Role of logged in User :
<sec:ifLoggedIn>
<sec:ifAllGranted roles="ROLE_ADMIN">
Admin resource
</sec:ifAllGranted>
</sec:ifLoggedIn>
(tested in grails-2.2.2 and springSecurityCorePlugin-1.2.7.3)
org.grails.plugins.springsecurity.service.AuthenticateService authenticateService = new org.grails.plugins.springsecurity.service.AuthenticateService()
def isAdmin = authenticateService.ifAllGranted('ROLE_ADMIN')
if(isAdmin) {
println 'I am Admin'
}
This question is pretty old, but I thought I'd post at least an answer that seems to work with Grails 2.0. If you are using the spring security plugin, there's a tag lib included called grails.plugins.springsecurity.SecurityTagLib.
The tag-lib has a protected method, hasAccess() which can take the same params map that you give the g:link tag. So, if you extend SecurityTagLib, you can call hasAccess() and get the behavior you want. Why this isn't externalized into a service that can be injected is beyond me as the functionality seems to fulfill an obvious need.
We use this to wrap the g:link tag and only generate a link of the user has access to the target page:
def link = { attrs, body ->
if( hasAccess(attrs.clone(), "link") ) {
out << g.link(attrs, body)
}
else {
out << body()
}
}
When dealing with permissions in views and taglibs, you can use the AuthorizeTagLib that's provided by the plugin.
For example, if you don't want a menu item to appear in your list for unauthenticated users, you might use:
<g:isLoggedIn>
<li>Restricted Link</li>
</g:isLoggedIn>
If you have more specific roles defined and those roles are tied to your controller/action request mapping, you can use other tags, such as:
<g:ifAllGranted role="ROLE_ADMINISTRATOR">
<li>Administrator Link</li>
</g:ifAllGranted>
In my experience, there's not yet a good way to tie the request mapping to your markup - I think you're going to have to use some of the above tags to limit access to content within a particular GSP.
I think that Burt Beckwith has a future modification (and is currently providing a beta version) to the plugin that integrates some ACL stuff that might solve this problem better in the future, but for now, I think the best approach is a hybrid request map + GSP tags one.
Not sure of the situation when this question was originally asked, but now you can check to see if a user is in a specific role by using SpringSecurityUtils.ifAllGranted() which takes a single String which is a comma delimited list of roles. It will return true if the current user belongs to all of them.
if(SpringSecurityUtils.ifAllGranted('ROLE_ADMIN,ROLE_USER')) {
Obviously, you can simply pass one role to the function if that is all you need. SpringSecurityUtils also has methods like ifAnyGranted, ifNotGranted, etc, so it should work for whatever it is you are trying to accomplish.
SpringSecurityUtils is a static API, so you don't need to create a private member named springSecurityUtils or anything like that.
You have to configure the file config/SecurityConfig.groovy (if it does not exists, create it, this overrides the default Security Configuration)
Add this entry:
requestMapString = """\
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/=IS_AUTHENTICATED_REMEMBERED
/login/auth=IS_AUTHENTICATED_ANONYMOUSLY
/login/authajax=IS_AUTHENTICATED_ANONYMOUSLY
/login/authfail=IS_AUTHENTICATED_ANONYMOUSLY
/js/**=IS_AUTHENTICATED_ANONYMOUSLY
/css/**=IS_AUTHENTICATED_ANONYMOUSLY
/images/**=IS_AUTHENTICATED_ANONYMOUSLY
/plugins/**=IS_AUTHENTICATED_ANONYMOUSLY
/**=IS_AUTHENTICATED_REMEMBERED
"""
This is means that you have to log in to enter the site. But all the resources (css, js, images, etc) is accessed without authentification.
If you want specific role only enter specific controller:
For example, for UserController:
/user/**=ROLE_ADMIN
/role/**=ROLE_ADMIN
For more information: http://www.grails.org/AcegiSecurity+Plugin+-+Securing+URLs
Regards
As far as I can tell, there doesn't look like there's an easy way to do it.
You can inject an instance of the grails AuthenticatedVetoableDecisionManager which is a concrete class of spring's AbstractAccessDecisionManager by doing this:
def accessDecisionManager
This has a "decide" method on it that takes 3 parameters
decide(Authentication authentication, Object object, ConfigAttributeDefinition config)
This is probably the method that you'd need to call and pass in the right things to figure out if the user with the auth creds can access that "object" (which looks like it's normally a request/response). Some additional digging around might prove out something workable here.
Short term, it's probably easier to use the ifAnyGranted taglib as another poster mentions.
I'm not sure about in Groovy, but in Java (so I assume Groovy too...) you could do (minus NPE checks):
GrantedAuthority[] authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
boolean isAdmin = false;
for(GrantedAuthority authority : authorities) {
String role = authority.getAuthority();
if(role != null && role.equals("ROLE_ADMIN")) {
isAdmin = true;
break;
}
}
As for knowing whether or not the action is supported, you'd have to call the RequestMap service to get the roles for the mapping and see if it contains the found user role.