http is not working in case of Web socket UI Client - sockets

I am using Websocket Programming in my Application
This is my Websocket Client from UI Screen .
When i use the protocol ws , It is contacting the server .
var wsUri = "ws://localhost:"+<%=request.getLocalPort()%>+"/Ravi/hello-html5";
websocket = new WebSocket(wsUri);
But if replace ws with http , its not cotatcing to the server .
That is with this url
http://localhost:"+<%=request.getLocalPort()%>+"/Ravi/hello-html5";
This is my web.xml
<servlet>
<servlet-name>HelloHtml5</servlet-name>
<servlet-class>org.Html5Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloHtml5</servlet-name>
<url-pattern>/hello-html5/*</url-pattern>
</servlet-mapping>
</web-app>
Please let me kow why http is not working ??

What happens when you call new WebSocket with a http uri? Is SyntaxError thrown or does your websocket's onerror or onclose callback run?
The JavaScript API and websocket spec are unclear on which url schemes are acceptable. If SyntaxError is being thrown, your browser is rejecting http as an invalid scheme. Other browsers may behave differently. If one of your callbacks is being run, the server is rejecting the connection. Other servers (you don't say which one you're using) may behave differently.

Related

Strange issue with Vertx Http request

I configured an HTTPS website on AWS, which allows visiting from a white list of IPs.
My local machine runs with a VPN connection, which is in the white list.
I could visit the website from web browser or by the java.net.http package with the below code:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://mywebsite/route"))
.GET() // GET is default
.build();
HttpResponse<Void> response = client.send(request,
HttpResponse.BodyHandlers.discarding());
But if I replaced the code with a Vertx implementation from io.vertx.ext.web.client package, I got a 403 forbidden response from the same website.
WebClientOptions options = new WebClientOptions().setTryUseCompression(true).setTrustAll(true);
HttpRequest<Buffer> request = WebClient.create(vertx, options)
.getAbs("https://mywebsite/route")
.ssl(true).putHeaders(headers);
request.send(asyncResult -> {
if (asyncResult.succeeded()) {
HttpResponse response = asyncResult.result();
}
});
Does anyone have an idea why the Vertx implementation is rejected?
Finally got the root cause. I started a local server that accepts the testing request and forwards it to the server on AWS. The testing client sent the request to localhost and thus "Host=localhost:8080/..." is in the request header. In the Vert.X implementation, a new header entry "Host=localhost:443/..." is wrongly put into the request headers. I haven't debug the Vert.X implementation so I have no idea why it behaviors as this. But then the AWS firewall rejected the request with a rule that a request could not come from localhost.

Pentaho CDA: Basic Authentication and CORS conflict

Working on a web app which queries Pentaho BI server 7 with a Tomcat 8 inside I'm facing some issues.
First of all to avoid CORS (Cross-origin resource sharing) problems I have added the CORS filter inside the web.xml config file of the tomcat:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Afterwards, everything was fine until it was necessary to get some resources through Pentaho CDA (Pentaho Community Data Access). I've added a Basic Auth header and one line in the plugin settings file (pentaho-solutions/system/cda/settings.xml):
<allow-cross-domain-resources>true</allow-cross-domain-resources>
Every request my aplication does gets the same error:
XMLHttpRequest cannot load http://localhost:8080/pentaho/plugin/cda/api/doQuery?path=/whatever/dashboard.cda&dataAccessId=mdxGetSmth. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:xxx' is therefore not allowed access. The response had HTTP status code 401.
The funny thing is that the same query is working in Postman (of course with the same Basic auth header) just because Postman just jumps over the OPTIONS (preflight) request.
Used Ngnix as Reverse proxy on Apache-Tomcat and resolved this CORS error

how can I stop the application part of the url being passed to my servlet in tomcat6

I am running tomcat6 and have hooked it up in eclipse as a server so I can quickly debug code changes - however I am running into an issue with the routes that are passed to my servlet.
I am running spring mvc3 with my routes annotated on the class eg:
#Controller
#RequestMapping(value="/rest")
public class HandleItController {
...
in web.xml I have
<welcome-file-list>
<welcome-file>welcome.html</welcome-file>
</welcome-file-list>
<servlet-mapping>
<servlet-mapping>handleit</servletmapping>
<url-pattern>/rest</url-pattern>
</servlet-mapping>
However I can only get one of these settings to work as desired at a time.
lets say "Web Project Settings" has Context root set to be appname
now if I GET localhost:8080/appname I will get the welcome page as desired
however if I hit localhost:8080/appname/rest/yadda I get a warning saying
No mapping found for HTTP request with URI [/appname/rest/yadda] in
DispatcherServlet with name 'handleit'
If I change my servlet url-pattern to / then I get request routed through the servlet without the appname prepended and the servlet handles them as expected - however I cannot then hit the welcome page
I need a solution that does not involve hard coding appname into the web.xml or the controller mappings, there must be some way I can serve both the html file and the servlet that is independent of the uri to which my application is deployed - ie stop sending the context part of the url through to the servlet
The URI in the #RequestMapping will be appended to the url-mapping of the dispatcher servlet. So if both the servlet and controller is mapped to rest, the full URI will become /contextpath/rest/rest. If you don't want that, map your controller to /
Edit: The reason it doesn't work when you map your servlet to / is that the Spring dispatcher servlet handles everything under the context root. So to get that to work, you need to configure Spring MVC to serve static files.

Securing Glassfish REST Service with basic auth using annotations

I have been trying to secure an application, which is deployed to glassfish 3 using annotation instead of the deployment descriptor. However, I haven't been able to get it working correctly. If I try to access the service, I end up with a server error 500, which displays this message:
type Exception report
message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: javax.ejb.AccessLocalException: Client not authorized for this invocation
root cause
javax.ejb.AccessLocalException: Client not authorized for this invocation
The EJB looks like this:
#Path("/myresource")
#Stateless
#RolesAllowed("user-role")
public class MyResource {
#GET
#Path("/{uuid}")
public Response getData(#PathParam("uuid") final String uuid) {
....
}
}
sun-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN"
"http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
<sun-web-app>
<security-role-mapping>
<role-name>user-role</role-name>
<group-name>user-group</group-name>
</security-role-mapping>
</sun-web-app>
This is the web.xml:
<web-app id="myservice" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>org.test.myservice</display-name>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.test.myservice.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>file</realm-name>
</login-config>
<security-role>
<role-name>user-role</role-name>
</security-role>
</web-app>
The file realm in glassfish is set up using the user and role specified in the sun-web.xml and has been working well, when setting up the application security via deployment descriptor.
If I understand this document correctly I do not have to link security role references if their names are the same. http://docs.oracle.com/javaee/5/tutorial/doc/bnbyl.html#bnbyt
Any ideas what I am missing?
Edit
Related to the problem of not being able to specify the required information with annotations, there is a another problem, which caused me to think about this issue. Maybe that will make the initial question a little clearer:
Taken above example, the resource /myresource/* is only available for users with role 'user-role'. However, if there is a second resource at path /myresource/*/thumbnail (translating to /myresource/[uuid]/thumbnail) which should be available without authentication, this is not possible by specifying security-constraints with url-mapping, since it does not seem to be possible to use the wildcard between constants. However, this would be doable by specifying the roles, that are allowed to access a method by annotions. As described above, I haven't been able to do so. How could a mapping like that be done?
You need to use the security-constraint element in web.xml descriptor in order to block specific resources and paths, and to specify the authorization constraints.
This doesn't mean that you can't add more fine-grained controls using Programmatic Security, as explained in Oracle's Java EE 6 Tutorial:
Programmatic security is embedded in an application and is used to make security decisions. Programmatic security is useful when declarative security alone is not sufficient to express the security model of an application.
As per your edited question.
I would use the security-constraint element for blocking the access to all non-registered users. This will force everybody to authenticate, so that your application knows the roles they have.
Then you can fine-grain control the access to the various resources using programmatic security.
With basic authentication I guess there are no other ways. If you want to avoid authentication for basic users, you need to go with form authentication and handle the authentication programmatically behind the scenes, authenticating them even if they aren't aware of, by using HttpServletRequest#login().
In both ways you should be able to setup rights in the way you have described. If you want to handle the unauthorized exception more smoothly, you'd better remove the #RolesAllowed annotation and instead use something like:
#GET
#Path("/{uuid}")
public Response getData(#PathParam("uuid") final String uuid, #Context SecurityContext sc) {
if (sc.isUserInRole("MyRole")) {
return result;
} else {
return notAllowedResult;
}
}
The Roles-Allowed is an EJB construct and not congruent with access to the resource, which is handled by the security constraint.
Unfortunately, the two security concepts do not mesh as well as they should, and instead of getting a 401 if you're not authorized (a web concept), you get the security exception that you are receiving (and EJB concept). In fact, I don't know what error you will receive if you annotate an EJB web service with a RolesAllowed and try to access the web service with an invalid role. I assume you'll get a SOAP fault, in that case.
The EJB security is a system that keeps unauthorized people out, but it's a last ditch effort. It assumes that any decisions to route folks to the method calls is already done up front. For example, there's no high level way to test if a method is allowed or not, rather you can only call it and catch the exception.
So the harsh truth is beyond coarse gatekeepers, you want to leverage Programmatic Security.

Rest - Jersey.Client pass #SecurityContext to Server

I want to pass a security context to my rest service.
On server side I try to get this with:
public Response postObject(#Context SecurityContext security, JAXBElement<Object> object) {
System.out.println("Security Context: " + security.getUserPrincipal());
.....
But actually the Syso is null.
On Client side im just doing:
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
client.addFilter(new HTTPBasicAuthFilter("user", "password"));
So, do I have to change in addition something in my web.xml to get it working?
I hoped its working without setting up static users in the tomcat user xml. So I can compare the user/password from security context with my "persistent" user/password hashmap located server sided. But when it is not working without tomcat user xml, how can it be done to add dynamically user to that user xml? When I ve static users I cant register a new user. I dont want to use this attempt: http://objecthunter.congrace.de/tinybo/blog/articles/89 cuz I want just to work with a semi persistence like a HashMap of user/password.
Besides another question: Why does everybody refer to Apache HttpClient when it is about security in Jersey, when it is working like I wrote as well?
My attempt refers to this post:
Jersey Client API - authentication
You need to set up your application on the server so that it requires Basic authentication. I.e. include something like the following in the web.xml in your application war file - otherwise Tomcat does not perform the authentication and does not populate the security context.
<security-constraint>
<display-name>Authentication Constraint</display-name>
<web-resource-collection>
<web-resource-name>all</web-resource-name>
<description/>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>authentication required</description>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>realm_name</realm-name>
</login-config>