I'm currently using openAM to protect a small webapp of mine using a Java EE web agent. Someone tries to access the app, they get redirected to the openAM instance, they login, they go to the app. Simple stuff.
What I'd like is for openAM to pass the username that was successfully used to the web app. It's my understanding that "session attributes" should be used for this. When in the admin, I go to my Java EE webagent and open up the "Application" tab to see the "Session Attributes Processing". I see that HTTP_COOKIE is a choice for fetching.
1) is it the case that I should expect to see the username, if properly set up, as plaintext in the cookie?
2) what value do I enter in the session mapping to get the username? How do I find what value in the data store corresponds to this?
Thanks
We are using HTTP_HEADER with our agents. So if you are already using agents (which sounds like you are), then the following should work for you. In OpenAM web console:
Access Control > Top Level Realm > Agents > Web / J2EE / etc. > click on an agent
Application tab > Profile Attributes Processing section > Profile Attribute Fetch Mode:
Click on the "HTTP_HEADER" choice
Profile Attribute Mapping:
Map Key: [uid] ... Corresponding Map Value: uid
Click Add. It should look like [uid]=uid once you've added it. Add any other mapping you need that matches attributes to your backend authentication system. Ours is ldap.
In your web application, retrieve the HTTP Header elements and look for the token. It should look something like this: AQIC5wM2LY4RfckcedfzxGrgVYevbKR-SgBkuemF4Cmm5Qg.AAJTSQABMDE.
You can then use the OpenAM REST interface to validate and retrieve attributes associated with the token such as user name, password, cn, etc. To retrieve all attributes, the URL would be like this:
http://<OpenAM_Host>:<Port>/<deploy_uri>/identity/attributes?subjectid=AQIC5wM2LY4RfckcedfzxGrgVYevbKR-SgBkuemF4Cmm5Qg.*AAJTSQABMDE.*
You can also specify attributes you want like this:
http://<OpenAM_Host>:<Port>/<deploy_uri>/identity/attributes?subjectid=AQIC5wM2LY4RfckcedfzxGrgVYevbKR-SgBkuemF4Cmm5Qg.*AAJTSQABMDE.*&attributenames=uid&attributenames=userpassword
References:
https://wikis.forgerock.org/confluence/display/openam/Use+OpenAM+RESTful+Services
http://openam.forgerock.org/openam-documentation/openam-doc-source/doc/dev-guide/index/chap-rest.html
1) yes, the agent will create plaintext cookies (and if the user sends malicious ones it will recreate them just fine), however using HTTP_HEADER method to pass on attributes is considered as a better solution (since it's not stored on the client side).
2) Session Attributes Processing only works if you actually stored something in the session. For that you can either use the "User Attribute Mapping to Session Attribute" feature in Authentication All Core Settings or write some custom module to save derivative values. Otherwise if you just want to get the uid of the user, then use Profile Attributes Processing (uid key HTTP_UID value and your app will see a HTTP_UID cookie/header).
Related
We have an existing OAuth2 based website. Our plan is to use a web based (XMPP over websockets) chat system.
now this chat system will be available once the user logs in. What we actually do not want is to login twice, once for the web site and once for the chat system.
So I figured how to trick it with my own auth provider and a custom username/password.
So basically the question is how do I have an object that I want to travel along with the user chat session so that I can provide out of band processing.
Does the session management allow this?
In a similar use-case, there I need to persist and store various pieces of information about a user, in Openfire, so that external calls and look-ups are not necessary during later, custom logic in an Openfire plugin. It is possible to add any number of custom properties to an openfire user, via REST, or other APIs.
Then, those custom properties can be retrieved as needed, without external calls.
create user api
Then, if using Internal APIs, you get
Get the session's username or address (JID)
call UserManager's getUser on the username or JID to get the User object
call User's getPropertyValue to get a specific property or getProperties to retrieve all custom user properties
I'm trying to get my standalone webapplication to use my Liferay 6.2 as "user store". That means I want the user to log in to Liferay and then be able to move on to another application with some credentials and user specific information passed as well. Moving on and passing information is already working, the issue I'm having right now is making sure the user-object that is passed on is the user that is actually logged in right now.
I use the LFR_SESSION_STATE_ cookie do determine the logged in user. But when I log in again with another user I get a second cookie with a different user-id. So now I need to make sure that I'm passing the correct user. The USER_UUID cookie does not contain the same uuid as provided by Liferay (as of now I didn't check if it's a hash of the uuid).
Long story short, I'm looking for a way to recognize the currently logged in user and be able to pass the credentials and additional information to my application.
I will take care of security concerns like manipulated cookies etc. subsequently. Maybe that will raise another question wenn I get to that point ;-)
I'd really appriciate any help or push in the right direction.
Thanks in advance guys ... sebastian
Some possibilities:
Make your application a portlet application
Publish your Liferay Database through LDAP (EE only) and use a separate SSO application
Create a Liferay-Hook that sets a cookie (to "/") containing the required user information - encryption and signatures are on yourself. You can create hooks that get executed on every successful login
In my Java web application,when a user gets logged in,i store the user name and other details in session as follows,
session.setAttribute("userName",username);
I am using ExtJs4 for UI.How to get the session variables in extJs?
Thanks
I can second #Geronimo approach. You need to get user Id and/or permissions when you authenticate the user. However...
You can't rely just on the username/permissions that you store somewhere in your JS code because it can't be easily spoofed. If you present user with some information that can be different for different levels of access you still need to do server side validation of the user identity.
You can't get session variables off the server web container using javascript only.
I do the same thing (storing userId as a session variable in java). I use Ext.Request to perform an Ajax request to a java servlet to get it (along with other data about the user like permission settings for the webapp to enable or disable features they wouldn't be able to use).
EDIT:
I second sha's answer also, the only reason I pass the authentication information back to the client is for cosmetic reasons - so that user doesn't think he can use a feature in javascript that would be denied by my server side authentication. If he were to spoof the userId or permissions and try to use the feature, the real authentication on the server side would stop him.
I understand that the question has been asked for a long time ago, but despite the large number of views and the absence of an plain answer, I decided to offer this answer:
Assume that the session variable is registered like /index.php?PHPSESSID=9ebca8bd62c830d3e79272b4f585ff8f
In this case, you can get the variable PHPSESSID through JS object "location" and transform it through Ext.Object.fromQueryString()
So:
console.log( Ext.Object.fromQueryString( location.search ) );
will prepare PHPSESSID variable for your needs.
I'm interested in how other people code this because I'm either not understanding it properly or I'm missing something or perhaps even I'm doing it right!
First of all, this is NOT an Active Directory instance of LDAP its OpenDS which other than some syntactical differences shouldn't much matter.
So assume I have my tree structure setup something like this:
-dc=somedomain,dc=com
-uid=rootuser
-ou=Group1
-uid=username1
-uid=username2
-ou=Group2
-uid=username3
-uid=username4
In order to authenticate as the 'rootuser' I would need to pass the fully qualified Username when I create my System.DirectoryServices.DirectoryEntry object, in this case:
uid=rootuser,dc=somedomain,dc=com
but for any other user in the tree I have to know in advance what LDAP path to append to the username to have them authenticate thru. So for example this will fail:
uid=username1,dc=somedomain,dc=com
but this will work:
uid=username1,dc=somedomain,dc=com,ou=Group1
So my question is how do you handle this when you don't know at login time what specific group a user belongs to to build that path? The only way I can figure to do it is to make the initial call as 'rootuser' so I have access to the entire tree then use System.DirectoryServices.DirectorySearcher to scan it for that particular user (i.e. username1)
using (DirectorySearcher searcher = GetDirectorySearcher()) {
searcher.Filter = "(&(objectClass=person)(uid=" + userName+ "))";
SearchResult result = searcher.FindOne();
return result.GetDirectoryEntry().Path;
}
at that point I have the path for the user I want to login and I can proceed with the actual auth. Am I way off base here or is this generally how it is done?
thanks!
You build a search filter on attributes that are unique to the user, e.g. screen-name, e-mail. Make sure LDAP is configured to ensure they are unique. Then you find the corresponding entry if any, get the DN, and rebind as that user with the appropriate password. If there was no such entry you react accordingly.
You don't say what language you are using, but in JNDI that means setting the DN as the security principal, the password as the credentials, and calling LdapContext.reconnect().
SASL supports the notion of using a username to authenticate. Your directory server administrator may be able to configure the directory server to map distinguished names to identities. Given the correct mapping it is possible for a client to authenticate without knowing the distinguished name. Professional-quality directory servers support a number of different mapping mechanisms such as direct mapping, exact match, regular expression, or a custom identity mapper.
I'd like to create a piece of code that can be embedded on many different websites (widget).
Is there any way that my code can identify a user without them logging in? I.e, can I use any of the established identity mechanisms floating around the web to reliably identify them across instances of this widget?
I don't need to (nor should I be able to) tap into any information about this user, just identify them.
The websites will be heterogeneous; there's no guarantee that they will have any common aspects, so the widget code needs to be entirely self contained.
What you want to do is what cookies were invented for. But browsers have gotten wise to people being tracked without their permission, and now limit 3rd party cookies.
The Electronic Frontier Foundation recently put up a proof of concept for uniquely identifying a visitor based on attributes of their browser. It's uses things things like:
User-Agent string
http-accept values
timezone
screen resolution and color depth
the installed plugins
if cookies are enabled
It's not guaranteed to be unique, but my browser certainly is, and it will get you on your way to doing the bad things that people don't like.
OpenID is sort of a SSO for the whole internet, yet they still have to sign in to OpenID. Other than that, I can't think of a solution.
I would suggest Open-ID rather than some workaround like this, but if you don't like that solution you might consider something like this:
You can use a cookie from a single domain, then use that domain to redirect to the correct site adding user-id as a parameter or part of the URL-path
For instance a link to add a personal widget on the foo.com -site, could look something like:
http://bar.com/addwidget1?backtoo=http://foo.com/main/
bar.com would own the cookie, change the user preferences and then add user-id to the back-link before re-directing:
foo.com/user-id/
Issues with this approach includes
You need to rewrite every page dynamicly with the user-id.
It's a bit clumsy I think
You can't fully take advantage of web-caches around the net.
The user might loose their cookie.
Benefits
No login
Since you redirect a lot you get stats on the users movement across your sites.
Sounds like you want to implement a Single Sign On framework. Basically when you first see the user, if you don't know them, you redirect them to the single sign on server. Wich authenticates them and redirects them back to you with a authentication token. You verify the authentication token with a web service call to the SSO server. Ff it is valid then you mark that user as signed on.
EDIT
So thinking about it more and reading tovare's answer and your comments. Why not create some javascript code that works like an google ads? You put the javascript on the page and it does an a request to your central tracking server using a dynamic iframe.
Have your tracking server return an image tag with src of the unique id (its own session id) embedded.
<img src=contentserver.com/track.php?id=12345668>
The content server has a server side script (track.php above) that maps its local session id to the unique id received from the tracking server.
The unique id stays the same across all sites.
Edit2
Instead of using an image, use the javascript trick. The content server just requests a javascript file from the tracking server. but the file is a dynamic one generated on the server side. it returns a generated javascript function called unique_id() it returns the unique id from the tracking server. Call the track.php using ajax to determine if this is a unique user.
Use OpenID, or a simplified variant, with your own site as the identity provider. Redirect the user to your identifier site which sets or checks a cookie, then redirect the user back with the user's identity, which was indicated by the cookie, added as a URL argument.
Your identifier site can be an OpenID identity provider which doesn't require any user interaction to authenticate. The sites which receive this identity are probably not OpenID consumers, since they don't offer the user a choice of providers. You can probably do away with some of the signing required by OpenID if your cookie and identifier are signed.
Facebook provides something similar; a site can find the Facebook identity of a user (assuming the user has one) without any action on the user's part.