I am developing an ordering web application and I am new to learning Grails. I used the Spring Security plugin. I haved configured and override the login and register, what I want is to get the currently logged in user to apply an order. Is there a way to do this without using the static belongsTo? Because using this always shows me a dropdown box where I can choose between the users and admins. Am I doing the right approach in getting the logged in user to order?
The simplest way to retrieve the currently authenticated principal is via a static call to the SecurityContextHolder:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
String currentUserName = authentication.getName();
return currentUserName;
}
OR
Inject SpringSecurityService bean,
like this into controller
def springSecurityService
and then call
def currentPrincipal = springSecurityService.principal
print "The details of current logged in user is" + currentPrincipal
For more details follow this link
http://www.baeldung.com/get-user-in-spring-security
How to get the current logged in user object from spring security?
Related
I need to achieve to authenticate users with their domain user/password, if they're are in the domain controller, but the application should be available for other users as well, who should be authenticated with their own username/password; this should be stored in the application database, and their username/password to be checked against the DB.
So far i started with new asp.net template in vs2015, choosing Individual User Accounts.
I'm able to authenticate users agains domain controller, but if that is succeeded I'm unable to store the user to HttpContext.User property.
In SignInManager i call PasswordSignIn and return Success or Failure depending on AD check.
public SignInStatus PasswordSignIn(string userName, string password, bool isPersistent, bool shouldLockout) {
if(AuthenticateAD(userName, password)) {
//
// to create identity/principal and assign to HttpContext.User
//
return SignInStatus.Success;
}
else {
return SignInStatus.Failure;
}
}
public bool AuthenticateAD(string username, string password) {
using(var context = new PrincipalContext(ContextType.Domain, "domainname")) {
return context.ValidateCredentials(username, password);
}
}
thanks for any hint!
The only way this really works is if you create proxy users in your application for users in AD. Essentially, you just set up a script that populates new users/updates existing users based on the data in AD on a schedule (nightly, etc. based on your needs). Then, you're dealing with just one type of user whether they're part of the domain or external. The only change you need to make is to selectively authenticate via AD or via the standard password authentication. Either way, the same user principal is in play.
You can use ADFS and allow users to choose where to authenticate. It is quite trivial to implement using default template. Just like usual login mechanics with Sign-in via google and local account.
I think this is most correct way of doing things, because domain users may end up with Kerberos/Ntlm, if they want, and it lowers complexity of your system.
Here is a WS-Fed example: Using Claims in your Web App is Easier with the new OWIN Security Components
For other stuff you can create app with default template. This app will have external authentication stuff as example.
I'm developing a Spring boot application using STOMP messaging over a websocket implementing an RPC pattern which exposes public (i.e.: without any need to be authenticated) and private methods.
Two public methods exists to register and authenticate the user, so I need to manually (programmatically) handle the user login, method accessed via a custom #MessageMapping operation.
The question is: how do I authenticate the user of the websocket session?
To make a similar thing using a normal MVC web application I would use a code similar to this:
#MessageMapping("/auth")
public Object auth() {
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_TEST");
SecurityContextHolder.getContext().setAuthentication(new PreAuthenticatedAuthenticationToken(myname, "dummy", authorities));
}
but this seems not work in a websocket environment because when the user a method like this:
#MessageMapping("/myendpoint")
public Object myEndpoint(Param params, Principal principal) {...}
I get the error:
org.springframework.messaging.simp.annotation.support.MissingSessionUserException: No "user" header in message
So the question is: how do I manually authenticate the user in the auth() method so that in myEndpoint() the Principal parameter is correctly resolved?
I had to implement a custom "authentication provider" for a project, but I ran into troubles when trying to acces the Authentication's object properties in JSP. Details:
My custom authentication provider successfully creates an Authentication object
Authentication auth = new UsernamePasswordAuthenticationToken(username, password, getAuthorities(userRoles));
log.info("User is authenticated");
return auth;
(Only relevant code here)
Then, in the controller method, I just display a log message with the username (this proves that the Authentication object is created and placed in the security context):
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
log.info("Welcoming user " + auth.getPrincipal());
Then in the JSP page I want to display the user name using
<sec:authentication property="principal"/>
However, this raises an error 500:
org.springframework.beans.NotReadablePropertyException: Invalid property 'principal' of bean class [org.springframework.security.authentication.UsernamePasswordAuthenticationToken]: Bean property 'principal' is not readable...
I also noticed that
<sec:authorize ifAnyGranted="role">...
is not working, although the user has the necessary roles added in the Authentication object.
Is there something I'm doing wrong? The authentication works fine, I just can't access the authentication object's properties.
Thank you very much and have a good day.
your AuthenticationProvider must return UserDetails object.
From spring documentation
This tag allows access to the current Authentication object stored in the security context. It renders a property of the object directly in the JSP. So, for example, if the principal property of the Authentication is an instance of Spring Security's UserDetails object, then using will render the name of the current user.
Given that I can't see anything wrong with your case, I think it can be SPR-8347 bug, which is fixed in Spring 3.1.1. Can you do an upgrade?
Old question, but I think that I can help other folks.
As the first parameter of UsernamePasswordAuthenticationToken you may send a User.
Instead of passing the username, pass the user itself. But the user must be a class that extends org.springframework.security.core.userdetails.UserDetails:
Authentication auth = new UsernamePasswordAuthenticationToken(user, password, getAuthorities(userRoles));
log.info("User is authenticated");
return auth;
See the method that you was using:
public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true); // must use super, as we override
}
Now, in yout tamplete, um can use something like this:
<span class="hidden-sm-down" sec:authentication="principal.email">Email</span>
In my application I have a top level entity called Organization. The relationship between User and Organization is many-to-many.
Because of this I could have the following scenario:
UserA has role ROLE_ADMIN for OrganizationA
UserA has role ROLE_USER for OrganizationB
I need to ensure that when UserA accesses resources for OrganizationB he is not doing it as an ADMIN. So I need an additional check that the user has the correct roles at the organization level. Is there anything built into Spring Security that allows for this? If not, does anyone know what the best way would be to about solving this?
UPDATE: A bit more information...
A User logs in and chooses which org they want to work with. That is stored in the session. Beyond that, URLs are locked down with the Secured annotation. What that means is that if UserA were to log in and select OrgA, they should be able to access /admin/user/create however, if they log in and choose OrgB they should not have access to that URL.
The long way is to add additional checks in every method where this matters. So call some service method that says "ok, you're an admin for OrgA but not for OrgB and you're logged in using OrgB, so deny this request".
I'm hoping for a more grails / spring-security way of handling this.
You can probably do this by using a custom AccessDecisionVoter. The vote method will supply you with the "configuration attributes" for the resource (method or URL), which will typically be the required roles, and you can obtain the current user's roles/authorities either directly from the Authentication object, or by reading the current org and selecting the appropriate roles for the user.
I'm assuming that you have some way of differentiating the user's roles, based on the org they've selected.
Essentially, you'd be writing an extended version of the standard RoleVoter, which takes the organization into account.
I think I'm little late here but this is what worked for me:
When an organization is selected, you can set a new Authentication object with new roles in your session(The previous Authentication object gets invalidated). Something like this:
#RequestMapping(value = "/org-a")
String orgA(HttpServletRequest request) {
request.getSession().setAttribute("org", "org-a")
Organization org = new Organization("org-a")
reloadRolesForAuthenticatedUser(org)
....
}
private void reloadRolesForAuthenticatedUser(Organization org) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication()
List<String> newRoles = getRoles(auth.getPrincipal().getUsername(), org)
List<GrantedAuthority> authorities = getAuthorities(newRoles)
Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(),auth.getCredentials(),authorities)
SecurityContextHolder.getContext().setAuthentication(newAuth)
}
private List<GrantedAuthority> getAuthorities(List<String> roles) {
List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>()
if (!roles.isEmpty()) {
for (String r : roles) {
auths.add(new SimpleGrantedAuthority(r))
}
}
return auths
}
Hi im trying to make facebook's login in a grails app, the problem I have is that when the user is logged in facebook, spring security core doesn't recognize him, how can I set the user's principal manually?
I can look for the user object but i don't know how to set it in order to get a true user when i call getAuthenticatedUser() (now it returns a null object)
Thanks in advance,
Regards
Cannot say anything regarding facebook, but Spring Security has a SecurityContextHolder that can be used to manipulate the authentication (and therefore the principal) like this:
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
....
def securityContext = SCH.context
def principal = <whatever you use as principal>
def credentials = <...>
securityContext.authentication = new PreAuthenticatedAuthenticationToken(principal, credentials)
Maybe you'll need to use a different implementation of the Authentication interface as the one used in the example.