In my web application, there are times when an authenticated admin might want to impersonate another valid user of a system without having to know that user's password.
How can I use Spring Security to give admin users the ability to impersonate normal (non-admin) users of the system?
The Spring Security documentation is silent on this and I can't find anything anywhere. Surely someone must have solved this.
Thanks!
It's in the Spring Security 3 and Spring Security 4 docs aptly named, "Run-As Authentication Replacement."
The AbstractSecurityInterceptor is able to temporarily replace the Authentication object in the SecurityContext and SecurityContextHolder during the secure object callback phase.
I believe the recommended way to do this in Spring Security is with the Domain Access Control lists, see GrantedAuthoritySid #
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/domain-acls.html
However, impersonating another user is more than just having a "delegate identity", you should also consider the implications on logging:
Do you want your logging to appear as Original User or Impersonated User (or both?)
Do you want the "impersonation" to show only what the impersonated user sees, or the superset of permissions of the Original User and Impersonated User?
Yet another possibility is to create a "log in as" feature, which essentially changes the principal identity of the current session - or starts a new session with the impersonated identity.
In all of the above, you may inadvertantly open up a security issue - so I think this is why impersonate-style features are not that common place. Rather, designs trend towards Role Based Access Control (RBAC) or Attribute Based Access Control (ABAC). Using RBAC / ABAC, you could create a delegate style feature where you create delegate attributes/roles - and in the special cases where you need to show the source/target of the delegation (e.g. for audit logs), you handle those as corner cases.
If you want an admin user to be able to impersonate another user (eg for QA/Testing purposes), have a look at the SwitchUserFilter
A decent example of the XML config you need is provided here
Related
We have recently switched to Keycloak to handle the login to our website.
It's still possible to register and Keycloak has a user registration page, but I basically need to change the definition of 'registrating'.
By default it means "insert a new user in the DB with the info given by the user through the registration form". But that's not what we want, we already have all the users that CAN register in our DB, and registrating as a user pretty much means updating a record in our DB.
I have already made changes to the a few classes and redeployed them by packaging them and then adding the Jar to the \deployments directory. But I can't seem to find the classes that I have to change to get the registration page to behave the way I want.
How can I change the default behavior of the registration page? What classes do I have to change?
I've never do this, but i'd take a look to the user store SPI and authenticator SPI.
I suggest you in writing directly in the Keycloak discourse forum (https://keycloak.discourse.group/) . They will surely give you a hand.
PS: with SPI you'll add features to Keycloak, but in your case i think that you'll need also to change the GUI. See Keycloak Themes in the official doc.
See Edit-1 below for sum-up question
I am using Spring Security libraries (v3.0.5) to handle authentication for a web application (deployed in JBoss AS7). The account management is handled by an IdM on top of OpenLDAP.
When a new account is created, by default it is created with the "nsaccountlock" operational attribute set to "true". We can confirm that the account is "Disabled" by logging into the IdM web portal and listing the users - new users are listed as Disabled.
The problem is that our web application seems to ignore that nsaccountlock attribute completely when it searches for a user entry. The springframework logs report "Enabled: true" for all accounts that attempt to authenticate, whether they have the nsaccountlock=true or false.
I have searched through as much of the springframework source code as I can find, and I can not find anything that is actually setting the "enabled" state to false (see org.springframework.security.ldap.userdetails.LdapUserDetailsImpl and any subclass). I would have expected it to happen in org.springframework.security.ldap.userdetails.LdapUserDetailsMapper.mapUserFromContext() but it definitely does not set the Enabled flag anywhere.
The LDAP lookup and entry retrieval is configured in several .xml files (which I am unfortunately unable to post here at the moment) that define the use of classes such as org.springframework.security.ldap.authentication.LdapAuthenticationProvider, org.springframework.security.ldap.search.FilterBasedLdapUserSearch, etc.
Should I be using a different type of org.springframework.security.core.userdetails.UserDetails implementation to capture the disabled state from LDAP? Am I missing some obvious configuration element that would indicate how Spring can determine the disabled state of the LDAP entry?
Note: I can configure the LDAP search to fetch the "nsaccountlock" as an attribute in the UserDetails response, and the attribute is logged correctly
(whether the value is true or false) but it still does not affect the "enabled" boolean value. It just acts as another bit of metadata (like phone, address, email, etc).
Edit-1
I may have been asking the wrong question up front. Ultimately, I would like to know this:
What would lead LdapUserDetailsImpl.isEnabled() to return false? i.e., What do we need to do in order to make sure Spring Security recognizes disabled accounts?
I'm hoping this a matter of configuration. I imagine it has something to do with the AuthenticationManager (we use org.jasig.cas.authentication.AuthenticatoinManagerImpl)
Thanks for the help, and I apologize for the messy question.
As far as I know OpenLDAP and the LDAP protocol, nsaccountlock is not an attribute which is used by OpenLDAP to keep track of locked account, it is an attribute which was used in Sun Directory Server (Sun LDAP Directory).
But from the point of view of OpenLDAP it is the same as any other informative attribute.
If you want to manage a password policy you have to implement the overlay ppolicy which is described here
I'm working on implementing a role-based authorization service under WS Liberty.
There are two main goals:
if the user without the correct user group tries to open a restricted url, show an error page
the user should see a menu, listing all pages available for him
My question is: are there best practices to implement this behaviour? Should I create the first part in server.xml AND the second part in the appropriate view?
(this way the "logic" will be stored in two different parts of the code, and for example if I have to add a new URL, I have to insert it into two different places)
So is there a way to store this role-URL mapping in one place?
Thanks,
krisy
In you application you can protect links checking roles (pseudo code, some frameworks have already custom tags for it):
if(request.isUserInRole("roleX")) {
// render menu item for roleX
}
By default, if user is already logged in and tries to access page that is restricted for him, he will receive 403 Not authorized, you can provide error page for that code via web.xml configuration.
In the server.xml via Application binding element you provide only mapping from your application roles to groups defined in the registry. Depending on the registry type you will be able to add/remove users to the given group granting or rejecting them right for example via server.xml or LDAP management tool in case of LDAP registry.
Hi I am actually trying to get tips or ideas on a very specific problem. The technology context is
java web app with JSF 2.1 .
So I have a simple java ee app powered by JSF 2.1. The structure is the following
\webapp
\WEB-INF
\templates
header.xhtml
menu.xhtml
web.xml
\secured
\operation1
op1.xhtml
\operation2
op2.xhtml
\operation3
op3.xhtml
userhome.xhtml
login.xhtml
I have one #WebFilter that restricts the access to /secured/* in case the 'user' bean is not set (Actually a Session Scoped Bean).
At the same time upon login, I create a dynamic Menu depending on the user credential. this menu (MenuItems) point to one or more operations (xhtml pages).
So far so good, the user logins, the menu is dynamic, links are being generated and upon clicking he/she can navigate to whatever operations he/she is supposed to do.
My problem is that I can not decide on an elegant way on restricting access to the absolute url of these pages . If user1 is 'authorized' to execute operation1 but not operation2 or operation3, currently I can not find the most elegant way on checking his session state and applying a generic rule (navigation rule?), if the actual web user, writes on the url bar the absolute path of the operation.
'/secured/operation1/op2.xhtml'
What is the most JSF2 compatible way on achieve that kind of requirement?
I have tried the preRenderView on each separate opxx.xhtml page , unfortunately it did not work + i dont like repeating it on each operation
Many thanks for your tips.
Security in web applications is a more advanced topic. Basically you have two ways:
Container based: This means your servlet container like Tomcat does the job for you (recommended)
Application based: You have to do the job on your own
How to setup container based security is explained in detail here. To summarize it, you have to implement a simple form (no JSF form!) with a specific action and specific ids for the username and password field. Afterwards you can easily restrict access to specific URL patterns using your web.xml file. In the web.xml file you restrict access to certain URL patterns for certain user roles. The mapping from usernames to user roles is done by a security realm. How to setup a security realm is desribed e.g. for Tomcat here.
If you want to implement security on your own, you have to implement a ServletFilter that inspects all requested URLs and either forwards users that are not logged in to your login form or passes the request through if the user is authorized. If the user is not authorized to see the page, you will have to forward the user to your error page. As CDI injection does not work for ServletFilter, you will have to lookup the bean that stores the information about your user (logged in, rights) from the HttpSession.
I am looking for a security framework for Java web application with Object granularity.
What it means is that I don't just want to filter by urls or by roles, but by specific user ownership of domain objects inside the system.
For example, if there is a Message object that has a Sender user and a Receiver user I would like to be able to configure it so that every Message can be RW by its sender and RO by its receiver.
Or for example, all user profiles are viewable by all users but editable only by the owner.
This rules, of course, I would like to define them with meta data (annotations, xml files, whatever) and not embedded in my business logic.
Is there such a beast out there? Preferably open source.
Spring Security can provide things like method security and "secure objects" using AOP.
You're looking for access control lists (ACLs). Like the other respondents I think Spring Security is worth checking out here--Acegi is just what Spring Security used to be called before they renamed it. Spring Security does have explicit support for ACLs (in addition to URL-based, role-based and group-based access controls). It supports both XML and annotation-based configuration. And you can apply ACL filtering to the view (using taglibs to decide what to render or suppress in the JSP), to methods that return a single domain object (decide whether to allow the method call to succeed), and to methods that return a collection (decide which objects to filter out of the collection before returning it).
You might be able to get away with rolling your own ACL code for simple requirements, but in my opinion ACLs can get tricky pretty quickly. Especially if you have lots of domain objects and you have to start taking performance management seriously.
Check out this link Acegi Security Fundementals - it's slightly outdated but still gives you the main concepts of Spring Security's object level authorization mechanisms.