How to obtain user principal from Liberty's FORM based authentication in JSF page? - jsf

So I have this JSF project that uses form based authentication. On the first attempt to open my JSF page, I get redirected to my login server. There the authentication takes place and on success I get redirected to my application. Unfortunately I don't know how to get the information that the authentication server provides, like username.
I have a page where a text is saying "Signed in as ". should be set by a ManagedBean with the method getCurrentUserPrincipal().
<h:outputText value="#{myBean.getCurrentUserPrincipal()}"/>
The method is currently empty. I tried it with WSSubject.getCallerPrincipal() and FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal() but that returned null.
How can I get the information I need with that method?
Is it even possible?
I'm not sure what information you would need, so if something is missing, I will provide if I can.

Inject the principal into your managed bean like:
#Inject
private Principal principal;
then, based on your html above for outputText field, provide a getter in your managed bean something like:
public String getCurrentUserPrincipal() {
return principal.getName();
}

After some digging I found out that our authenticating server was a siteminder service and the informations came back in a cookie (SMSESSION) and header information of the response.
So, it would be enough to read the header information to get the user name.
But the principal or subject would still return null. To get this and also make security working, I added a TAI to Liberty. How this is done, you can read here and here. My myTAI.jar is really simple. Because I have a ldap registry configured, I need the user security name (String, e.g. uid=..,ou=..,ou=..) of the given username (header) for further authentication and return this:
return TAIResult.create(HttpServletResponse.SC_OK, userSecName);
In the background Liberty will then do some further authentication and creates the principle and subject. If everything is correctly configured and the user is authorized to enter the application, he will and will have principle and subject objects available.

Related

socialauth - can you use same session across a redirect?

I'm trying to use socialauth to login with google, facebook et al (I'll assume google here) and have a question about how it works. I'm using JSF 2 without Seam. The basic idea is that you:
make a few API calls indicating that you want to login with google.
make another API call which returns a URL for google.
supply a result URL which will be used by google to redirect back to your site.
redirect to the google URL.
then google will either immediately redirect back to your site or first ask for login details.
My confusion is about linking together the data from the outbound and inbound sides. In the getting started page (linked above) they suggest this:
Outbound
SocialAuthManager manager = new SocialAuthManager();
String successUrl = "http://my.domain.com/socialauthd/successAction.xhtml";
String url = manager.getAuthenticationUrl(id, successUrl);
// Store in session
session.setAttribute("authManager", manager);
Inbound
// get the auth provider manager from session
SocialAuthManager manager = (SocialAuthManager)session.getAttribute("authManager");
The problem I have is that I don't see how this can work, and it doesn't in testing. They suggest storing a reference to an instance of SocialAuthManager in the session, however when the request is received from google a new session is created. It doesn't have the JSESSIONID cookie and so isn't part of the session that sent the request to google in the first place.
To work around this I got a unique per-request id from the socialauth api (openid.assoc_handle - it's sent as a query param), put it in a concurrentHashMap in an app scoped bean, and retrieve the reference in a preRenderView listener in the completion page (successUrl - badly named in the example as it is called either way).
This all seems like a lot of hassle for something that isn't included in the documentation. I've tried this with #RequestScoped CDI beans, although I usually use CODI #ViewAccessScoped. With CODI I've tried adding the windowId to the success URL, and also adding the JSESSIONID cookie to the redirect, but neither approaches work. I don't think the bean scope is relevant but the more information the better.
I could dive into the spring, seam and struts examples but for a pure EE 6 developer it's a lot of overhead, and with a better understanding of this issue I can produce a simple, working, JSF only example which I will make available to the socialauth team for use on google code.
Am I missing something obvious or does this just have to be complicated? and if so why did they document an approach that simply doesn't work?
Edit: I think that the successUrl may be named more appropriately than I thought, because in testing with Yahoo I realise that you won't be redirected back to your own site unless correct login details are provided. I expect this is the same for all providers. I have added some comments regarding this solution to the socialauth site, and also to an issue I logged about this problem (neither of which have received any response from anyone involved in the socialauth project).
Include the jsessionid path parameter in the callback URL.
String successUrl = "http://my.domain.com/socialauthd/successAction.xhtml"
+ ";jsessionid=" + session.getId();
Note that this is not specific to JSF API, but to Servlet API (chapter 7.1.3, URL rewriting).

j_security_check dilemma - work around

Before implementing j_security_check using MySQL realm authentication in my web app. I had the form info sent to a servlet (action controller) which would authenticate the user and then add some info regarding the user to the session object. Other servlets could then make use of this session object. After implementing j_security_check I dont know how to add the details of the login to the session object since j_security_check is being called instead of my controller and then it forwards to the requested page. Its like as soon as a user signs in - the data specified on the form is needed to create the session object , however i currently cant find any way of accessing the data submitted since its being passed to j_security_check. I tried using filters but i cant seem to read the submitted data directed towards j_security_check.Any suggestions on what i should do (I just want to set a session object as soon as a user signs in)
The only information you can get in j_security_check is username and password. I don't see a use case of storing password in the session.
But, anytime the username can be obtained using HttpServletRequest.getRemoteUser()

How can I write a "user can only access own profile page" type of security check in Play Framework?

I have a Play framework application that has a model like this:
A Company has one and only one User associated with it.
I have URLs like http://www.example.com/companies/1234, http://www.example.com/companies/1234/departments, http://www.example.com/companies/1234/departments/employees and so on. The numbers are the company id's, not the user id's.
I want that normal users (not admins) should only be able to access their own profile pages, not other people's profile pages. So a user associated with the company with id 1234 should not be able to access the URL http://www.example.com/companies/6789
I tried to accomplish this by overriding Secure.check() and comparing the request parameter "id" to the ID of the company associated with the logged in user. However, this obviously fails if the parameter is called anything else than "id".
Does anyone know how this could be accomplished?
You could have a simple #Before function, or if it is only on the view page that you want to apply the security, then you could have a simple bit of code at the beginning that checks the user's id (I assume from the session), and checks that they are allowed to access the page, by getting the User form the id in the session, and the Company from the id passed in, and checking against each other.
If security fails, then either return a badrequest instead of render, or call an action that shows a notAuthorised custom page.
You could make a SecureProfileController class that extends Controller, has a method that does the checkCompanyId-that-is-to-be-viewed against users companyId, and let the controllers that need that logic extend the SecureController.
If the method is an #Before function, like Codemwnci says, then it can intercept all the action methods in the inherited classes.
Alternatively you could have a look at Deadbolt, where you can setup roles for users and restrict access based on those roles: http://www.playframework.org/modules/deadbolt-1.0/home
Hope that helps :)

How to restrict some module of GWT based application from accessing it directly via url

I have to secure a section of my GWT based application from accessing it directly via some url.
Actually there is an index page which is login page. The use gives credentials and enters into the app (the module to be saved).
Currently what I am doing is that when a user logs in I save his username into session ( session.setAttribute(“username”, username) ) and load the required view of user.
Now whenever user navigates the application I call a method via RPC which checks if the “username” attribute is set or not in the session; if it is set then method returns true and false otherwise.
And of course if it returned false then I load the index view of application (which says user to log in).
Now I have to call this method before I load any module which should be accessed by loggined user only to restrict illegal access via url etc.
From the scenario given above kindly guide me; if it is the right strategy to secure some module. Or are there other good ways to do the same thing.
Cheers!
Raza
While your approach would work, I feel a Servlet Filter is the best place to authorize web server requests. Since all the requests have to pass through the filters before hitting the servlet, this is the best place to make proceed/abort/redirect decisions, based on the url pattern and your session attributes.
Having ( /* ) security filters also ensures that all your web app requests pass through the authorization test first, leaving the servlet code to just do the business stuff.

Handling form security

So how do you maintain the form security about posting data to different page problem? For instance you have a member and he/she tries to change the personal settings and you redirected member to
www.domain.com/member/change/member_id
member changed the values and post the data to another page by changing the action with firebug or something else. For instance
www.domain.com/member/change/member_id_2
How do you handle this problem without using sessions?
This problem arises when there are no server side validations!
So, the solution is to have server side validations.
Why not use Session state? It's designed for that.
Alternatively use cookies or URL's with unique session style ID embedded in it, which allows you to tie it back to a specific user.
How do you handle members without session?
Before modifying anything, check if the current user has the right to do so. For example, if you're user #1 and your details are at /members/change/1, you post to the same url, and with firebug you change the form to point to /members/change/2. When processing the form, you have to check if the userid in the form is the current user's id, and if not, display an error.
You could crypt the identity information (member_id) and add it as parameter or url path. When the request is posted to the member_id form, you can verify that the crypted member_id (which is part of the request) matches the member_id.

Resources