Primefaces dialog framework + SSO url rewriting - primefaces

I have problem with opening dialog using Primefaces dialog framework. We are using SSO solution to provide security to our application by integrating with internal company SSO solution.
In short.
Our real address (without sso) to application on our server is e.g.: https://appserver1.net/ctx/page.xhtml (where ctx is root context of our app)
In normal case we get sso address e.g.: https://ssoaddress.net/junction/page.xhtml
where junction=ctx. During request sso address is rewritten to find real address of our server, get resources and response again rewritting to sso url address. Everything works fine. But we got second env (DEV02) on which due to some limitation we got sso addres where junction!=ctx like: https://ssoaddress.net/junction/ctx/page.xhtml. In that case when i am trying to open dialog i got information: "page.xhtml Not Found in ExternalContext as a Resource".
Working code when junction=ctx:
public void openTestPage() {
Map<String,Object> options = new HashMap<String, Object>();
options.put("resizable", false);
options.put("draggable", true);
options.put("modal", true);
options.put("height", 250);
options.put("contentHeight", "100%");
options.put("closable", true);
RequestContext.getCurrentInstance().openDialog("/pages/page", options, null);
}
Due to fact that junction is different than context during rewriting is not possible to find requested page.html. Maybe someone of you knows how to solve this problem? I add that i cannot rewrite context of application.
Technical info: primefaces 6.0, JSF2.2, weblogic 12.2.1.
structure of resources: src/main/webapp/pages/page.xhtml

Since you can't fix bad url rewriting due to some limitation, you're left with fixing it with another rewriting.
You may put in a separate proxy between your server and sso, that does the rewriting.
Or you may rewrite right in your app. You may create your own rewriting servlet filter or use a 3rd party solution, e.g. PrettyFaces.

Related

U2F with multi-facet App ID

We have been directly using U2F on our auth web app with the hostname as our app ID (https://auth.company.com) and that's working fine. However, we'd like to be able to authenticate with the auth server from other apps (and hostnames, e.g. https://customer.app.com) that communicate with the auth server via HTTP API.
I can generate the sign requests and what-not through API calls and return them to the client apps, but it fails server-side (auth server) because the app ID doesn't validate (clients are using their own hostnames as app ID). This is understandable, but how should I handle this? I've read about facets but I cannot get it to work at all.
The client app JS is like:
var registerRequests = // ...
var signRequests = // ...
u2f.register('http://localhost:3000/facets', registerRequests, signRequests, function(registerResponse) {
if (registerResponse.errorCode) {
return alert("Registration error: " + registerResponse.errorCode);
}
// etc.
});
This gives me an Error code 5 (timeout error) after a while. I don't see any request to /facets . Is there a way around this or am I barking up the wrong tree (or a different forest)?
————
Okay, so after a few hours of researching this; I'm pretty sure this fiendish bit of the Firefox U2F plugin is the source of some of my woes:
if (u.scheme == "http")
if (url2str(u, true) == url2str(ou, true))
return resolve(challenge);
else
return reject("Not matching appID");
https://github.com/prefiks/u2f4moz/blob/master/ext/appIdValidator.js#L106-L110
It's essentially saying, if the appID's scheme is http, only allow it if it's exactly the same as the page's host (it goes on to do the behaviour for fetching the trusted facets JSON but only for https).
Still not sure if I'm on the right track though in how I'm trying to design this.
I didn't need to worry about facets for my particular situation. In the end I just pass the client app hostname through to the Auth server via the secure API interface and it uses that as the App ID. Seems to work okay so far.
The issue I was having with facets was due to using http in dev and the Firefox U2F plugin not permitting that with JSON facets.

Web API call not returning

I have a RESTful Web API that is running properly as I can test it with Fiddler. I see calls going through, I see responses coming back.
I am developing a tablet application that needs to use the Web API in order to fetch data or make updates in the repository.
My calls do not return and there is not a single trace in the Fiddler to show that my calls even reach the server.
The first call I need to make is to login. The URI would be this:
http://localhost:53060/api/user
This call would normally return some information about the user (such as group membership, level of authorization and so on). The Web API uses Windows Authentication, so the repository is able to resolve all these fields based on the credentials passed in. As I said, in Fiddler I see the three calls made to the URI as the authentication is negotiated between the caller and the server. The third call returns with a JSON object that contains all information generated from the repository as expected.
Now, moving to my client I have the following:
var webApiClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true
})
{
BaseAddress = new Uri("http://localhost:53060/")
};
webApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await webApiClient.GetAsync("api/user");
var userLoginInfo = await response.Content.ReadAsAsync<UserLoginInformation>();
My call to "GetAsync" never returns and, like I said, I see no trace of it in Fiddler.
Any idea of what I'm doing wrong?
Changing the URL where the Web API was exposed seemed to have fixed the problem. Thanks to #Nkosi for the suggestion.
For anyone stumbling onto this question and asking themselves how to change the URL of the Web API, there are two ways. If the simulator is running on the same machine with the Web API, the change has to be made in the "applicationhost.config" file for IIS Express. You can locate this file by right-clicking on the IIS Express icon in the Notification Area (the bottom right corner) and selecting show all websites. Highlight the desired Web API and it will show where the application host configuration file is located. In there, one needs to locate the following section:
<bindings>
<binding protocol="http" bindingInformation="*:53060:localhost" />
</bindings>
and replace the "localhost" name with the IP address of the machine where the Web API is running.
However, this approach will not work once you start testing your tablet app with a real device. IIS Express must be coerced into exposing the Web API to the outside world. I found an excellent node.js package that can help with that. It is called IISExpress-proxy.

REST API for yii2, the authenticator (HttpBearerAuth) is not working on server

I've just created a project for working with REST API (using yii2 framework).
All issues of REST API is working really cool on localhost. But when bringing the project on server (also the same database is taken by), the authorization is not available. Now I'm using "yii\filters\auth\HttpBearerAuth"
Inside the model "implements IdentityInterface", there's finding-token function "findIdentityByAccessToken" that's so simple, the "validateAuthKey" function is returning always true; see below:
public static function findIdentityByAccessToken($token, $type = null){
return static::findOne(["token" => $token]);
}
public function validateAuthKey($token)
{
return true;
}
See any pictures:
https://www.flickr.com/photos/40158620#N03/20701523349/in/dateposted-public/
Anyone can have some experience on this problem, can you tell me how to solve it? Thanks for your kindness.
Note:
The project, I'm following https://github.com/NguyenDuyPhong/yii2_advanced_api_phong (It works fine on localhost; I also deployed exactly the project on my server, it raised the same problem )
To make sure that the server is configured right: I created 2 actions, 1 is authorized, another is not. I checked unauthorized action, it works very well. =======>
actionView is not authorized => getting API info. is ok
actionIndex is authorized by "yii\filters\auth\HttpBearerAuth" => FAIL
In my case the Problem was that the server removes Authorization Header
I needed to add this to .htaccess
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
HttpBearerAuth used $user->loginByAccessToken to authorize see
validateAuthKey used by "loginByCookie"(and it seems that in this case not used)
Try to use QueryParamAuth for test purposes (it's easier to test)

How to fix cross-site origin policy for server and web-site

I'm using Dropwizard, which I'm hosting, along with a website, on the google cloud (GCE). This means that there are 2 locations currently active:
Some.IP.Address - UI
Some.IP.Address:8080 - Dropwizard server
When the UI tries to call anything from my dropwizard server, I get cross-site origin errors, which is understandable. However, this is posing a problem for me. How do I fix this? It would be great if I could somehow spoof the addresses so that I don't have to fully qualify the resource in the UI.
What I'm looking to do is this:
$.get('/provider/upload/display_information')
Or, if I have to fully qualify
$.get('http://Some.IP.Address:8080/provider/upload/display_information')
I tried setting Origin Filters in Dropwizard per this google groups thread (https://groups.google.com/forum/#!topic/dropwizard-user/ybDOTOxjlLI), but it doesn't seem to work.
In index.html that is served by the server at http://Some.IP.Address you might have a jQuery script that look as follows.
$.get('http://Some.IP.Address:8080/provider/upload/display_information', data, callback);
Of course your browser will not allow accessing http://Some.IP.Address:8080 due to the Same-Origin-Policy (SOP). The protocol (http, https) and the host as well as the port have to be the same.
To achieve Cross-Origin Resource Sharing (CORS) on Dropwizard, you have to add a CrossOriginFilter to the servlet environment. This filter will add some Access-Control-Headers to every response the server is sending. In the run method of your Dropwizard application write:
import org.eclipse.jetty.servlets.CrossOriginFilter;
public class SomeApplication extends Application<SomeConfiguration> {
#Override
public void run(TodoConfiguration config, Environment environment) throws Exception {
FilterRegistration.Dynamic filter = environment.servlets().addFilter("CORS", CrossOriginFilter.class);
filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
filter.setInitParameter("allowedOrigins", "http://Some.IP.Address"); // allowed origins comma separated
filter.setInitParameter("allowedHeaders", "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");
filter.setInitParameter("allowedMethods", "GET,PUT,POST,DELETE,OPTIONS");
filter.setInitParameter("preflightMaxAge", "5184000"); // 2 months
filter.setInitParameter("allowCredentials", "true");
// ...
}
// ...
}
This solution works for Dropwizard 0.7.0 and can be found on https://groups.google.com/d/msg/dropwizard-user/xl5dc_i8V24/gbspHyl4y5QJ.
This filter will add some Access-Control-Headers to every response. Have a look on http://www.eclipse.org/jetty/documentation/current/cross-origin-filter.html for a detailed description of the initialisation parameters of the CrossOriginFilter.

Web browser control with single sign on to reporting services

My goal is to perform Single sign on functionality from my WPF application which has a embedded browser . Single sign on needs to be implemented for this so that the user should not be asked to enter this credentials again to check the reports from the wpf browser. I need to create a local environment for testing this functionality from my side since I am developing for a product i.e a sql report which has forms authentication and logging to the report from my application. I have browsed almost everything on the net regarding this implementation and the sample provided by microsoft for forms authentication is not working. I also find certain condition that the sample will not work in Itanium based processors etc.. and I am working on ssrs 2012. Sign on with capturing the DOM of reporting site and peforming the login wouldn't be a good idea since this is for a product and reporting login will not be same. I am thinking of implementing with Httpwebrequest and Response, but still not clear on implementing. Some one please provide me crisp and working solution for my implementation. Thanks in advance.
Some one please provide me crisp and working solution for my
implementation.
I wouldn't count on that, especially if you're asking for a source code solution.
Single sign-on assumes that you still have an authentication server somewhere, something like Google OAuth. From your question, it isn't quite clear to me if that's what your looking for. If you just need to supply custom credentials to WebBrowser control, that's still possible, but that solution is for WinForms version of WebBrowser control. The WPF version is sealed from customization, so you may have better luck hosting the WinForms WebBrowser in your WPF project, using WindowsFormsHost.
I finally found the way for Implementing single sign on for reporting services. The standard way for implementing single sign on for forms authentication is by using custom security extension sample. The configuration is a bit tricky, But once the configuration is done single sign on needs to be done by getting the auth token by calling Logonuser() methon in reporting service. The below code passes the credentials and returns auth token.
Configuring forms authentication can be found detailed here
http://www.codeproject.com/Articles/675943/SSRS-2012-Forms-Authentication
The below code helps me to achieve single sign on.
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool InternetSetCookie(string lpszUrlName, string lpszCookieName, string lpszCookieData);
private void GetAuthToken(string username, string password)
{
// Step1: Add reference to report service either by directly referencing the reportinservice.asmx service of by converting wsdl to class file.
ReportServerProxy2010 rsProxy = new ReportServerProxy2010();
//Step2: Assign the report server service eg:"http://<servername>/ReportServer/ReportService2010.asmx";
rsProxy.Url = string.Format(ReportServerUrl, ReportServer);
try
{
rsProxy.LogonUser(username,password, null);
Cookie authCookie = rsProxy.AuthCookie;
if (authCookie != null)
{
//Internet Set Cookie is a com method which sets the obtained auth token to internet explorer
InternetSetCookie(Url, null, authCookie.ToString());
}
}
catch (Exception ex)
{
}
}
//When navigating now, the auth token is accepted and report manager page is displayed directly without asking for login credentials.
WebBrowserControl.Navigate(new Uri("");}