Grails: How to get username of currently logged in user, and what imports does that require? - authentication

I simply need the name of the currently logged in user. The same that gets displayed in gsp with <sec:username/>. I'm at a loss as to what to do.
Here's previous answers and questions - they all seem to require some import and none of the solutions works for me:
Grails Spring Security (get current user)
How to get id of the current user logged in grails?
How to get current_user by using Spring Security Grails plugin in GSP
Grails and Spring Security: How do I get the authenticated user from within a controller?
Specifically, I want to access the username insides a controller and put it into a variable of a domain instance in order to persist it (alongsides other information) into the database for logging purposes. Insides that controller, there's nothing to be seen that even remotely refers to Person/User classes, spring security or any other thing that sounds like it might do what I intend.

You can access the domain object corresponding to the logged-in user using springSecurityService.currentUser, and then fetch the username (or whichever other properties you require) from there. Due to Groovy's dynamic nature you don't need to import the domain class or the SpringSecurityService class to do this, simply using an untyped dependency injection
def springSecurityService
and you can access springSecurityService.currentUser?.username (or whatever).
Though as Burt points out in a comment, if it's only the username you want then it is more efficient to use springSecurityService.authentication.principal.username as this does not need to load the user object from the database. You only need currentUser if you want other properties of the user object aside from the ID or username.

Just figured it out: In the controller, def springSecurityService comes just after the opening bracket of the controller class (that's class YourController {) and the variable assignment looks like this: def username = springSecurityService.authentication.principal.getUsername() - apparently playing around with some code posted here has helped me.

Related

Spring secutiry custom authentication manager vs custom provider vs custom UserDetailsService

I've been knocking my head up against this problem for a few days now and after seeing dozens of examples all over the web I'm no closer to a solution.
I need to to various types of login, eventually. For right now I'd settle for one. I would like to login using fields other than username and password. Let's say I want to use name, last name and birthdate.
I thought the easiest way to go was to just implement my own UserDetailsService and plug it into my provider. But UserDetailsService only has one method, loadByUsername, which doesn't seem to be the most intuitive way to load my user.
So then I thought it would be better to implement my own AuthenticationProvider ... or simply extend DaoAuthenticationProvider, and override the authenticate() method. But that method takes an Authentication as a parameter ... can I used a POJO, with only name, last name and birthdate fields, as an Authentication object?
Ditto for Authentication Manager. In fact, in the api for AbstractUserDetailsAuthenticationProvider (where the authenticate() method lives) it says that it "Performs authentication with the same contract as AuthenticationManager.authenticate(Authentication)"
But people seem to implement Providers more than Managers. oddly enough, most examples of "custom" Providers and UserDetailsServices ... all implement authentication with username and password, which is was Spring Security does by default anyway!
Can anyone shed some light on this subject? As I said, there are tons of examples but they are all very similar and none that I can find use an Authentication Object that isn't username/password.
Bonus points if someone could also tell me the best way to go about having more than one Provider/Manager -- for example, one like the one described above, and another that authenticates using name and social security number, for example -- and to use one or the other (not both, and not the second one if the first one fails!) depending on a parameter pass from the url, for example.
I'm not sure if you had already solved this challenge. But, it seems that I have a similar case with you. My login page requires additional field 'organisation' aside from 'username' and 'password'. Here is what I did:
I've used custom AuthenticationManager and custom UsernameAndPasswordAuthenticationFilter.
The custom filter is for retrieving the additional field from HttpServletRequest. I added the field to the session and retrieved it inside custom AuthenticationManager.
Performed authentication with the three fields using another bean/service.

Accessing Deadbolt user from within Controller

I am using Deadbolt 2 with Playframework 2.1.
In the getSubject() function of my DeadboltHandler I check the user password and retrieve the user from the database.
Is it possible to access this user in my controllers to avoid retrieving the user twice per request?
Steve, the developer of Deadbolt, suggested me the following:
the trick is to store the user in the context, and then have your controller or deadbolt handler to access it. This allows you to store the user by the actual class, and not have to use getSubject() and cast the resulting Subject to your actual User class.
So I decided to save the User object in the args-Field of Http.Context.current() and it works like a charm!

Yii RBAC, Role change in runtime

I am building up a dynamic RBAC system for Yii and I don't know how to handle this problem:
The moderators can change the roles of the Users, furthermore the User can change it too by getting a different qualification (let's say achievement, so s/he can do more stuff and it can happen both ways).
What happens, when the role is changed Backwards (a role with less right) or Forwards (a role with more right) when s/he is logged in? Cannot access the functions he just got the right to use? Or can still access the functions until a logout/relog action?
Thanks your help in advance.
The effect of changing the authorization assignment will be inmediate.
Only the successive calls to IWebUser::checkAccess() issued in the same request may return cached values, since the default implementation of IWebUser, i.e. CWebUser, uses a static attribute to cache the calculated permissions.
To clarify the procedure, you will be calling IAuthManager::revoke() on the old permissions and IAuthManager::assign() on the new ones.
Edit
Sometimes you store session information through the IWebUser::setState() method; if the state of the currently logged user shall change along with the permissions, e.g. you store the current user's role name, you must take this into account and either call IWebUser::clearState() or IWebUser::logout() followed by IWebUser::login() –the latter also clears the cached permissions in the CWebUser implementation.
CWebUser::_access is declared private, so you will have to declare a new attribute if you want to override the default implementation.

Rails 3: How Does One Restrict Access to IDs

This might be very simple; I don't know Rails very well.
I have a match myController/myAction/myID in my routes.rb that will direct hyperlinks to the proper page (using link_to). But here's the problem: I don't want people to be able to freely modify the id parameter, passing in via the URL whatever they like.
Is there a way to perhaps restrict access to routes to the link_to method only? Or maybe there's another way to go about this, using a passed in hidden variable param or something?
Users access you site via urls like: /controller/action/:id right? A user can change an id and must not view another non authorized resource. How to achieve this?, on your controller, return only those resources that user is allowed to access.
For example, suppose that you are using devise:
class AController < ApplicationController
def index
#resouces = current_user.find_all_by_id params[:id]
end
end
This way if the user tries to access something he does not have access to, he will get an error.
Hope this helps, if not please let me know and I'll try to elaborate.
About current_user, yes it is supposed to be the current logged in user, it doesn't have to be devise, you can implement your own session handling logic and then create a helper method to retrieve the currently logged in user.
About using devise, if you don't want to implement your own session handling logic, plus if you want features like:
remember me
already created views that you can fully customize
authentication
authorization
password encryption
many more (please look at the docs for further information)
Then devise is a good way to go.
Also, it is always a great idea, if possible and as a learning exercise, implement your own authentication and authorization layers, you won't regret.
Best regards
Emmanuel Delgado

Play Framework User Authentication/Membership

I want to support user authentication in a Play Application. It is Web App and I think that the built-in "Secure" module is too simple for my needs. In fact, the user group discusses how the Secure module is really for demonstration purproses. However, how can I develop such a system?
Essentially, the application will allow the user to login and then they will have their own settings and so forth applied throughout the application. There are some pages for which unauthenticated users can view but if the client is authenticated, then the view of those pages will be different. Pretty simple setup but most documentation just refers to the simple Secure module.
If your only special requirement is that some pages be publicly visible, I've got your answer: Play framework: How to require login for some actions, but not all . I just copied the Secure module and made a few small additions.
You can use the PlayPlugins for this. I started to write a plugin which enabled Security in powerful way. It's an migration from BasisSecurity for Grails. At the moment I don't find the time to further development. You can see the current state here https://code.launchpad.net/~opensource21/+junk/permsec.
from your requirements the current authentication module seems enough. If not, what I did for my project was:
Copy the classes from the module (Secure controller, the annotation, the tag) to your project
Extend the controller adding additional functionalities
I don't have my code handy to put samples here, but in general I:
renamed the classes (so apologies if I say one name meaning another, don't remember the original names!)
added methods in Secure Controller to handle OpenId and OAUth authentication
added support methods in my User model that given the Id of a service (Google OpenId, Twitter id, etc) returns an existing user from the DB with that ID, or if it doesn't exists creates and returns a new user linked to that id.
added some flags (like admin, supervisor, etc) to User class
modified the check method in security controller so it checks the values of the annotation with the flags of the user. Something like (pseudocode)
var ok : Boolean = false
ok = ok || (annotation.value == "admin" && currentUser.isadmin)
ok = ok || (annotation.value == "supervisor" && currentUser.issupervisor)
...
added the annotation to the corresponding methods, and added the Secure controller (via #With) tot he classes that require access check
With this I have a secured system, and it seems to work quite well (fingers crossed :P)
Don't know if it could help you but look at the deadbolt module to manage access rights to views/controllers...
http://www.playframework.org/modules/deadbolt-1.0/home