Programmatically create subdomains with JBOSS and java - java

Right now I am developing an application on JBOSS 7.1 using JSF, SEAM and Primefaces. The application is providing a user registration. What I need is when the user registers an account for the nickname for example "andrew", his profile will be publicly accessed as andrew.mysite.com.
How can I implement this programmatically.
Thanks in advance,
Ilya Sidorovich

This is simply a process of mapping your subdomain to URL's that can be accessed by the appserver and use something like REST to map the URL to request parameters.
In your example, you will probably need a webserver like Apache web server to handle the incoming requests that can do some URL rewriting. Something like this
user.mysite.com --> www.mysite.com/user
In Apache this can be achieved by creating a virtualhost and using RewriteCond and RewriteRule. Here is an example
RewriteCond %{HTTP_HOST} ^([^.]+)\.mysite\.com$
RewriteRule ^/(.*)$ http://www.mysite.com/%1/$1 [L,R]
You can then forward your requests from the webserver to your application server. If using Apache this can be done using mod_jk, mod_proxy or mod_cluster.
Once you have that, you can create a RESTFul service (jboss supports REST) that can map the URL to your application code. Here is an example
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
#Path("/")
public class UserService {
#GET
#Path("/{param}")
public Response printMessage(#PathParam("param") String user) {
String result = "User : " + user;
return Response.status(200).entity(result).build();
}
}

Related

Handle unauthorized error message response body in Tomcat

I'm setting up authentication for a portion of a webapp using standard servlet container authentication (web.xml security entries) plus Tomcat Realm capabilities (to read users and roles from a database).
Everything seems to fit my requirements except one aspect: since the authentication will guard our REST APIs, I'd like every response to be in JSON format.
But with the tools I'm going to use, when there's a failed authentication Tomcat sends back a response with an HTML body.
I found this question on Spring that addresses the same issue, but it relies on Spring components.
Is there any customization possible using only servlet and Tomcat components?
From first glance, simple solution may look like custom error page for error code 401 (or any other).
Look for answer there:
how to specify the default error page in web.xml
P.S. Probably you can also use custom Servlet filter to handle content for error.
Because you're using a standard JAX-RS provider you can take advantage of the standards that exist. Normally you'd want something like:
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
#Provider
public class MyExceptionMapper implements ExceptionMapper<RuntimeException> {
#Override
#Produces(MediaType.APPLICATION_JSON)
public Response toResponse(RuntimeException exception) {
return Response.status(Response.Status.FORBIDDEN)
.entity("{\"error\": \"your error message\"}")
.type(MediaType.APPLICATION_JSON)
.build();
}
}
The hard part here is that the exceptions vary between JAX-RS providers. So, while I may get a RuntimeException with RestEasy (and I know that I do) the exception may be different with Jersey. If you implement an exception mapper that just takes Exception you can quickly figure out what type of Exception is thrown with your JAX-RS provider.
The advantage of this is that it is mostly standard in that you could move to another app server and it would not be Tomcat specific.

Secure EJB3.1-Webservice (in JBoss Wildfly 8.2)

I have a nearly finished web project with EJB3.1 deployed as WAR in Wildfly 8.2. It´s secured by a self-written JAAS-realm with form authentication (auth-method FORM).
Now I want to add a EJB-Webservice which is basically defined as
#Stateless
#WebService
public class ProductImportWebservice {
#Resource
WebServiceContext wsContext;
[...]
#WebMethod
public Product createOrFind(String name) {
[...]
}
}
The webservice works as expected but now I have the problem that I want to protect access to the Webservice by username/password.
So I annotated the webservice or the #WebMethod with
#RolesAllowed("ADMIN")
which is a valid role in the JAAS-authentication.
Effect: The SOAP-client gets the answere "reqeust not allowed / not authenticated" - but gets no authentication-request and attempts with BASIC-authentication are ignored.
If I add the URL of the webservice to the security-constraint in the web.xml I get an authentication request... but the problem now is that it´s the form based authentication - as a user with a browser would expect it. This is unusable for a "normal" SOAP-client :-(
The concrete question now is: Is there a way to have both - BASIC authentication for the webservice and FORM-based authentication for the rest of the application?
The only other way I would see is to split the WAR package up to an EAR-package and deploy the webservice in a different web-context.
The concrete question now is: Is there a way to have both - BASIC
authentication for the webservice and FORM-based authentication for
the rest of the application?
You can't use both FORM and BASIC authentication for the same web application.
If you need to do this, create two separate applications, with a shared codebase.
Reference:
https://docs.oracle.com/javaee/7/tutorial/security-webtier002.htm#JEETT01227
The auth-method subelement configures the authentication mechanism for
the web application. The element content must be either NONE, BASIC,
DIGEST, FORM, or CLIENT-CERT.

Open html file on Tomcat server in Restfull web service

I hava a small web service which is running on tomcat server and i want to open my html file on my tomcat server.
My web service is:
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("myresource")
public class MyResource {
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getIt() throws Exception {
String url = "E:/this.html";
File htmlFile = new File(url);
Desktop.getDesktop().browse(htmlFile.toURI());
return "Got it!";
}
}
These answers are based on the potential questions in the comments section of the question.
Q: Which url do I put in your browser to see the message "Got it!"?
A: http://localhost:8080/myresource
However, that might not be the exact case for you. There are lots of ways of setting up a web container (like tomcat) and you will have to verify what port you're running on and what your servlet context is. The above answer assumes that you are running on your local machine, under port 8080 (which tends to be the default for java web servers) and under the ROOT context.
A more complete answer would be:
http://<host_name>:<port>:<context>/myresource
Q: How do I allow the End User to say which file they want to download?
A: This is a HUGE security risk. Allowing an End User to enter a path to a file on the server is just not smart. No offense...
The End User could just enter {/etc/passwd} and depending on which system user was used to start your web container, the web container will serve that file. Not a good situation.
Q: Ok, great, so how do I allow a user to download a file from my web container?
A: There are several ways of doing this and I won't go into great detail, but, you could allow the container to serve the files themselves directly. Meaning place the files inside of the /webapp directory itself. Then your web container will serve them automajically.
You could set a directory in your MyResource classes constructor and only serve requested files from that particular directory. You would need to do some serious validation on End User input to verify that they aren't asking for a file like this: ../../../../etc/passwd
Q: FINE, got it, so I'll do validation, NOW, how do I actually serve the file to the End User? I promise I'll be careful...
Well, that is easy, just go take a peek at this question here:
what's the correct way to send a file from REST web service to client?

Deploying web service on cloud

Developed an web service , below are the steps
1) Create a Web Service Endpoint Interface..
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
//Service Endpoint Interface
#WebService
#SOAPBinding(style = Style.RPC)
public interface HelloWorld{
#WebMethod String getHelloWorldAsString(String name);
}
2. Create a Web Service Endpoint Implementation ..
import javax.jws.WebService;
//Service Implementation
#WebService(endpointInterface = "com.abc.ws.HelloWorld")
public class HelloWorldImpl implements HelloWorld{
#Override
public String getHelloWorldAsString(String name) {
return "Hello World JAX-WS " + name;
}
}
Create a Endpoint Publisher...
import javax.xml.ws.Endpoint;
import com.abc.ws.HelloWorldImpl;
//Endpoint publisher
public class HelloWorldPublisher{
public static void main(String[] args) {
Endpoint.publish("http://localhost:9999/ws/hello", new HelloWorldImpl());
}
}
Now I have also tested the deployed web service by accessing the generated WSDL (Web Service Definition Language) document via this URL “http://localhost:9999/ws/hello?wsdl” .
But My query is that as I new to the world of cloud , I want to deploy my webservice to cloud like amazon so that If I provide the wsdl to anyone in the world he can access my wsdl through his browser as my web service is deployed on cloud.
Please advise me how to achieve this..!!
This aproach will not work when you deploy your application to a real server on the cloud because you cannot execute your main method to publish the web service.
You need to configure something to publish your web service when your application starts on server.
For example, using Spring, to run an SOAP Web Service on Tomcat you need to inject your WS beans and use the SimpleJaxWsServiceExporter bean to publish it, these configurations are realized on your application-context.xml or equivalent.
In your case, take a look on this link, it is an example of how to publish an WSDL Web Service using JAX-WS RI distribution.
For tests, you can deploy your WAR application to Openshift.
Hope it helps,
Best Regards.

How do I find the URL of my web service?

I know this might seem a stupid question but I am just not able to find any information regarding this question.
I have a java web service (generated using NetBeans) and inside the web service class I would like to know the URL at which the web service was deployed.
For example, if I am deploying the web service on my local glassFish server, the web service is available at "http://localhost:8080/MyService/" where "MyService" is the name of my service.
The reason I need to know this URL is because my web service generates some files that I need to make available at this URL. For example, the web service call returns a URL "http://localhost:8080/MyService/report.html"
I have found some links about "WebServiceContext" but I am not able to get the URL at which my web service is running.
Edited
To clarify: Inside MyWebService.java class I want to find out the URL at which my web service was deployed (in this case, my web service is running at "http://localhost:8080/MyService/", but once it is deployed on a production server, this URL will change)
Easier in my opinion, for example:
#GET
public URI redirectSendMail(#Context UriInfo ui) {
return ui.getBaseUri();
}
If we want to send a String back to the client, indicating the exact path of some resource, we might want something like this.
#GET
public String getResourcePath(#Context UriInfo ui) {
return ui.getAbsolutePath();
}
If you are asking how to find the hostname (e.g. 'localhost' or 'www.example.com') that your servlet container is listening to you have a few options:
Add a configuration point that is set at deployment time (e.g. config file, system property)
Look into if your servlet container exposes any 'virtual host' configuration via JMX or read its config files (e.g. tomcat hosts)
Find the IP Address of the server and do a DNS lookup to get its configured hostname
Inspect the 'Host' header of the incoming HttpServletRequest
String hostname = request.getRequestHeader("Host");
Add the below property in your webservice class.
#Resource
private WebServiceContext wsCtxt;
Now below code snippet will give you the values you are looking for:
MessageContext msgCtxt = wsCtxt.getMessageContext();
HttpServletRequest request =
(HttpServletRequest)msgCtxt.get(MessageContext.SERVLET_REQUEST);
String hostName = request .getServerName();
int port = request .getServerPort();
to check from where the webservice was invoked, use the below code.
String clientIP = request .getRemoteAddr();
Related imports are below:
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import weblogic.jws.Context;
import weblogic.wsee.jws.JwsContext;
Hopefully I am able to help you, I have just recently started working with webservices (Jersey REST) and I have found that the url to your endpoint is :
'http://localhost:8080/MyService/XXX/YYY'
where XXX = the URL pattern in the servlet mapping in your web.xml file (eg. file below)
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
and the YYY is the path defined by your webservice's #Path() parameter so in the case of this example it would be something like:
'http://localhost:8080/MyService/rest/myPathDefinition'
Another thing to note is that you can in fact change the web context root in eclipse, though it will default to the name of your Java project. Please let me know if you need further clarification or if this did not help / someone can expand on it.
It could be found on your wsdl file as:
therefore: http://localhost:8080/TestSOAPWebservice/services/TestClassImpl?wsdl would be the url to your wsdl file.

Categories

Resources