how to apply filters in jsf - jsf

I have a filter and I get Page not Found error when any client requests a JSF page in my web application. I don't know how to fix this issue.
Here is my filter code:
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession ses = req.getSession(true);
String pageRequested = req.getRequestURL().toString();
if (ses.getAttribute("userDetails") != null) {
fc.doFilter(request,response);
} else {
RequestDispatcher dis = request.getRequestDispatcher(LOGIN_PAGE);
dis.forward(request,response);
}
I have done all the necessary settings in web.xml deployment descriptor.

A 404 simply means that the requested resource is not found. Down to the point this can have 2 causes:
The URL is invalid (i.e. LOGIN_PAGE is invalid).
The resource is not there where you think it is.
To further nail down the cause in this particular problem we need to know 2 things:
What is the absolute URL of the current request? Print request.getRequestURL().
What is the absolute URL with which you can open the login page independently in webbrowser?
Then, you should be able to extract the correct LOGIN_PAGE from this information.

Related

How to get string query params from URL in Domino

After some time I managed to make a redirect from some API.
However, now I'm facing a different problem.
It seems, that there's just no way to get a query param from URL.
The button looks like that:
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
var redirectUrl = context.getUrl().toString();
var errorRedirectUrl = context.getUrl().toString();
var EGRZAuthObject = new ru.iteko.egrz.requestprocessors.EGRZAuthorization();
//auth which redirects
EGRZAuthObject.initializeAuthProcess(redirectUrl, errorRedirectUrl);
print("marker param is " + param.get("marker"));
print("marker param is " + facesContext.getExternalContext().getRequest().getQueryString());
print("url " + context.getUrl().toString());
}]]></xp:this.action>
</xp:eventHandler>
The method which redirects is as follows:
public static void initializeAuthProcess(String redirectUrl, String apiRedirectUrl) throws ClientProtocolException, IOException
{
CloseableHttpClient httpclient = HttpClients.createDefault();
try
{
HttpContext context = new BasicHttpContext();
String urlToGoTo = AuthURLs.ESIALoginURL(redirectUrl, apiRedirectUrl);
HttpGet httpGet = new HttpGet(urlToGoTo);
HttpResponse response1 = httpclient.execute(httpGet, context);
HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(
HttpCoreContext .HTTP_REQUEST);
HttpHost currentHost = (HttpHost) context.getAttribute(
HttpCoreContext .HTTP_TARGET_HOST);
String redirectURLEsia = (currentReq.getURI().isAbsolute()) ? currentReq.getURI().toString() : (currentHost.toURI() + currentReq.getURI());
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext externalContext = fc.getExternalContext();
externalContext.redirect(redirectURLEsia);
}
finally
{
httpclient.close();
}
}
Here's what happens:
In a browser the user initializes auth process by pressing the button
Then initializeAuthProcess executes a request to the system A
System A takes us to the system B, we redirect the user there
The user goes through authorization process in the system B
System B (after auth) redirects the user to our system
And it appends some sort of token in our system's URL called marker
Later on, we should do something with the marker...
The problem is that we don't know how to get the marker. It's always either null or empty. In a browser, however, we always can see it after auth in the system B successfully completed.
I get the following output:
marker param is null
marker param is
url https://oursystem.com/Nav2.xsp
We also wondering how to remove it from the URL after processing is completed. But as of now, we need to get it at least.
How can we do that?
Thanks in advance.
EDIT:
Obviously the thing is that the code gets executed immediately without waiting for the user authorization in the system B.
For instance if we press the button again we'll have marker param.
So we need a different approach there we should define marker and do something with it
You looking at the wrong end. There are 2 options: pick the marker from the returned response1 calling the other systems or move that code to the page you redirect to
If you click the button, you are redirected to the other page. Testing for the marker should therefore be in the callback step between 5 & 6. Check in the beforeRenderResponse event if the marker is there and then you can react to that.

How can I use Scribe with JSF to connect to the LinkedIn API?

Based upon the Scribe example on github, I'm trying to authorize my application to use LinkedIn's api.
Here is my current code that is tied to a button click:
public String generateFromLinkedIn() {
OAuthService service = new ServiceBuilder()
.provider(LinkedInApi.class)
.apiKey(apiKey)
.apiSecret(apiSecret)
.callback("http://localhost:8080/Project/faces/linkedIn.xhtml").build();
ExternalContext externalContext = FacesContext.getCurrentInstance()
.getExternalContext();
Token requestToken = service.getRequestToken();
String authUrl = service.getAuthorizationUrl(requestToken);
try {
externalContext.redirect(authUrl);
} catch (IOException ex) {
Logger.getLogger(LinkedInController.class.getName()).log(Level.SEVERE, null, ex);
}
Map<String, String> parameterMap = (Map<String, String>) externalContext.getRequestParameterMap();
Verifier v = new Verifier(parameterMap.get("oauth_verifier"));
Token accessToken = service.getAccessToken(requestToken, v);
OAuthRequest request = new OAuthRequest(Verb.GET, "https://api.linkedin.com/v1/people/~");
service.signRequest(accessToken, request);
Response response = request.send();
System.err.println(response.getBody());
return "";
}
And in my .xhtml page I have:
<h:commandButton value="Generate" action="#{linkedInController.generateFromLinkedIn()}"></h:commandButton>
Everything works okay until I try to get the Verifier from the parameter map, which does not have any oauth_verifier. I tried splitting it up into multiple methods, but so far I cannot obtain the oauth_verifier from the URL parameters even though it is clearly there after returning from LinkedIn authorization dialog.
Any suggestions on how to get this verifier correctly or how to make Scribe work with JSF?
You seem somehow to expect that the redirected request magically returns to exactly same location in the code and continues from there. This is untrue. It are effectively 2 HTTP requests. You're basically still fiddling around in the parameter map of the current request (the one which called the generateFromLinkedIn() method).
After you call redirect() you should be returning from the method. You should move the remainder of the code into the #PostConstruct or <f:viewAction> of the backing bean tied to linkedIn.xhtml. It's the one who's called with the parameter.

jsf Response already committed

I'm working in JSF and trying to redirect a page if the user has already selected a language (I know that from a cookie).
So I've set a listener :
<f:event listener="#{languageSelectionController.checkSkipLanguageSelection}" type="preRenderView" />
that check if the cookie is present and if so redirect to the home page (without propose language choice page)
if (languageBean.isValidCookieDetected()) {
FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(FacesContext.getCurrentInstance(), "languageSelection.xhtml", "toHome");
}
But I get an exception
java.lang.IllegalStateException: Response already committed
at weblogic.servlet.internal.ServletResponseImpl.objectIfCommitted(ServletResponseImpl.java:1602)
at weblogic.servlet.internal.ServletResponseImpl.sendRedirect(ServletResponseImpl.java:833)
at com.sun.faces.context.ExternalContextImpl.redirect(ExternalContextImpl.java:576)
at com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:182)
I've read the post What exactly does "Response already committed" mean? How to handle exceptions then? and try to raise the buffer size but it changes nothing.
UDPATE :
I've set a filter with the following code :
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
Cookie[] cookies = httpServletRequest.getCookies();
for (Cookie c : cookies) {
if (c.getName().equals("lang")) {
httpServletResponse.sendRedirect("home.xhtml");
}
}
chain.doFilter(request, response);
But I still got the Response already committed exception...
Can anyone help me ?
Thanks
Stephane

Transferring from http to https in Glassfish 3.1.1

I'm using Glassfish 3.1.1 and JSF 2.0:
I have the following code:
public String doLoginOrCC() {
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
this.flightNumber = request.getParameter("flightNumber");
if (request.getRemoteUser() == null) {
return "login.xhtml";
} else {
return "https://" + request.getLocalAddr() + ":8181" + request.getContextPath() + "/bookSeat.xhtml";
}
}
If user is not logged in then go to login.xhtml.
If user is logged in then go to https://localhost:8181/APP/bookSeat.xhtml
Unable to find matching navigation case with from-view-id '/flightInfo.xhtml' for action '#{bookSeatController.doLoginOrCC}' with outcome 'https://127.0.0.1:8181/PlaneTicketProgram5-war/bookSeat.xhtml'
Do I have to add a Navigation Rule in my faces-config.xml file.
If so how would I write the Navigation Rule?
You cannot change the HTTP scheme by a navigation case. A navigation case does basically a forward. You need to send a HTTP redirect instead. You can use ExternalContext#redirect() for this.
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.redirect("https://" + request.getLocalAddr() + ":8181" + request.getContextPath() + "/bookSeat.xhtml");
You only need to add a throws IOException to the bean action method.
Unrelated to the concrete problem, why aren't you logging in over HTTPS? Your problem suggests that you're logging in over HTTP which thus sends the username/password unencrypted over network. Also, grabbing the raw Servlet API from under the JSF covers should be avoided as much as possible. You can grab HTTP request parameters by ExternalContext#getRequestParameterMap() or, better, by #ManagedProperty or <f:viewParam>. You can get the remote user by ExternalContext#getRemoteUser().

JSF 2.0: How to get the URL that is entered in the browser's address bar

My JSF application redirects any user who is not logged in to the login page. When the user logs in, I want the application to redirect to the page the user has initially entered in the browser's adress bar. But I don't know how to access the url the user has initially entered, since he is automatically redirected to the login page which I configured in the web.xml.
The container managed security doesn't have any API-provided facilities for this. Your best bet is to replace the <login-config> by a Filter class which does roughly like this:
HttpServletRequest httpreq = (HttpServletRequest) request;
HttpServletResponse httpres = (HttpServletResponse) response;
if (httpreq.getUserPrincipal() == null) {
httpreq.getSession().setAttribute("from", httpreq.getRequestURI());
httpres.sendRedirect("login.jsf");
} else {
chain.doFilter(request, response);
}
And then in your login thing:
request.login(username, password);
externalContext.redirect((String) request.getSession().getAttribute("from"));

Resources