SOAP Header using JAX-WS(Server Side) - java

The requirement is to include security attributes in header of Soap Message in every WebService request. One way to include is:
#WebService
#SOAPBinding
(
style = javax.jws.soap.SOAPBinding.Style.DOCUMENT,
use = javax.jws.soap.SOAPBinding.Use.LITERAL
)
public interface UserService
{
#WebMethod
public AuthenticateResponse authenticateUser(AuthenticateRequest request, #webParam(header=true) ApplicationCredential appcredential);
#WebMethod
public UserDetailResponse getUserDetail(UserDetailRequest request, #webParam(header=true) ApplicationCredential appcredential);
}
But, with the above mentioned approach, I need to include ApplicationCredential at every operation. It doesn't look good. I am looking for if we can include this ApplicationCredential class in BaseRequest Class and mention there that it is going to be a part of Soap Header(through some annotaion), that would be really helpful. For ex:
public class BaseRequest
{
#SomeAnnotation which states that Appcedential is a part of Soap Header
ApplicationCredential appcredential;
}
So far, I am unable to find any way to do this. Any help would be highly appreciated.

I know it's a while ago you asked that question, and you may have found out yourself already, but I answer to it anyway: Try to avoid to create your own authentication handshake for Web Services - instead use either Web Service message level security if your server and client provide it, or just use transport level security, e.g. Basic Authentication and/or SPNEGO.
The selection of the authentication mechanism depends mainly on your context: If you provide the service within a company network, use whatever is provided there, or Basic Authentication if no central authentication infrastructure is in place. If you provide your Web Service to the Internet, the easiest way to do authentication is again Basic Authentication (via SSL), but that again depends on the kind of service consumers you envision.
This answer creates more questions, I guess, sorry about that. My main point is that you should not try to reinvent the wheel again =:-)

Related

XACML application on SOAP Web Services

I'm new to web-services and i would like to know the answer to some questions.
First, i know that REST APIS can be consumed just by having the URL of the rest endpoint, on the other side (SOAP), you can't consume any distant SOAP WS unless you develop a client. Is it correct? And if it is, is it the only difference between the 2 big families ?
Second, i would like to apply XACML on some SOAP Web Services for security purpose of course. I made a figure that resumes the entire process of XACML.
I developed some basic SOAP web services with simple 2 methods, and i don't know from where should i start the XACML code and configuration. I'm asking you guys for some good and helpful links to apply the XACML security filter.
You can find an example of CXF interceptor doing XACML-based (XACML 3.0) authorization on Colm O hEigeartaigh's blog (Colm is one of the main CXF developers). The actual source code of the CXF Interceptor: XACML3AuthorizingInterceptor. It is using OpenAZ as XACML implementation, but you can adapt it to use another XACML implementation, such as Axiomatics mentioned here by David Brossard, or AuthzForce (supporting embedded or remote RESTful PDP modes), or other implementations mentioned at the end of the XACML TC's page.
The first important part of the CXF Interceptor is at the beginning of the handleMessage(Message message) method:
SecurityContext sc = message.get(SecurityContext.class);
The SecurityContext gives you information about the authenticated user such as the user roles, which you can use as XACML subject attributes in the XACML request.
The code further creates the XACML Request using the DefaultXACML3RequestBuilder class, that extracts other information from the CXF Message using CXFMessageParser - that you can find in the cxf-rt-security-saml library - such as the SOAP service name, operation name (as defined in the WSDL), and the endpoint URI:
CXFMessageParser messageParser = new CXFMessageParser(message);
...
String actionToUse = messageParser.getAction(action);
...
QName serviceName = messageParser.getWSDLService();
QName operationName = messageParser.getWSDLOperation();
...

Implement basic Authentication for rest api using Jersey 2

I have exposed some rest api using Jersey 2(Tomcat server) and successfully implemented Basic authentication(only needed authentication stuff not authorization) using ContainerRequestFilter filter as below
public class AuthFilter implements ContainerRequestFilter{
#Context
HttpServletRequest request;
#Override
public void filter(ContainerRequestContext context) {
............................
//getting username/password authorization header and validating
When I told the same to my Lead, he said don't use filters as every time your rest api is hit, this filter will get invoked.Therefore, implement basic authentication security at container level.I am using Tomcat server.
In web.xml, this is defined
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
Is the above he is referring to?
Can anyone please guide me how to implement the way my lead is saying?
The documentation gives you examples on how to configure this via web.xml. You'll need to configure this using a login-config that belongs to a realm. The web container then takes care of securing resources based on URL patterns.
Note that the data is sent in plain text (in encoded form) via a HTTP header, so you'll need to think of ways to ensure that is not snooped on (like HTTPS).
Whether you check this header on a filter or on the container does not relieve you of the overhead required for making the check (which is probably negligible, but I've never profiled this area of the code to quote numbers).

Securing REST services in Jersey

I am very much new to web services. I have exposed some REST services using Jersey 2 in integration with Spring. Now I need to secure those rest services using authentication with username/password. I am told not to use Spring Security.
I have no idea of how to do this. I did search on the net but various links show various implementation and I am unable to decide how to proceed with it.
A common way for authenticating with username and password is to use Basic Authentication. Basically the client needs to send a request header Authorization, with the the header value as Basic Base64Encoded(username:password). So is my username is peeskillet and my password is pass, I, as a client, should set the header as
Authorization: Basic cGVlc2tpbGxldDpwYXNz
In a servlet environment, the container should have support for Basic authentication. You would configure this support on the web.xml. You can see an example in 48.2 Securing Web Applications of the Java EE tutorial. You will also notice in an example
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
That is for SSL support. This is recommended for Basic Authentication.
If you don't want to deal with the hassle of working with security domains and login modules, realm, and such, that would be required to customize the servlet support, or if you're just not in a servlet environment, implementing Basic Auth in a ContainerRequestFilter is really not too difficult.
You can see a complete example of how this could be done at jersey/examples/https-clientserver-grizzly. You should focus on the SecurityFilter
The basic flow in the filter goes something like this
Get the Authorization header. If it doesn't exist, throw an AuthenticationException. In which case the AuthenticationExceptionMapper will send out the header "WWW-Authenticate", "Basic realm=\"" + e.getRealm() + "\", which is part of the Basic Auth protocol
Once we have the header, we parse it just to get the Base64 encoded username:password. Then we decode it, then split it, then separate the user name and password. If any of this process fails, again throw the WebApplicationException that maps to a 400 Bad Request.
Check the username and password. The example source code just checks if the username is user and the password is password, but you will want to use some service in the filter to verify this information. If either of these fail, throw an AuthenticationException
If all goes well, a User is created from the authenticate method, and is injected into an Authorizer (which is a SecurityContext). In JAX-RS, the SecurityContext is normally used for authorization`.
For the authorization, if you want to secure certain areas for certain resources, you can use the #RolesAllowed annotation for your classes or methods. Jersey has support for this annotation, by registering the RolesAllowedDynamicFeature.
What happens under the hood is that the SecurityContext will be obtained from the request. With the example I linked to, you can see the Authorizer, it has an overridden method isUserInRole. This method will be called to check against the value(s) in #RolesAllowed({"ADMIN"}). So when you create the SecurityContext, you should make sure to include on the overridden method, the roles of the user.
For testing, you can simply use a browser. If everything is set up correctly, when you try and access the resource, you should see (in Firefox) a dialog as seen in this post. If you use cURL, you could do
C:/>curl -v -u username:password http://localhost:8080/blah/resource
This will send out a Basic Authenticated request. Because of the -v switch, you should see all the headers involved. If you just want to test with the client API, you can see here how to set it up. In any of the three cases mentioned, the Base64 encoding will be done for you, so you don't have to worry about it.
As for the SSL, you should look into the documentation of your container for information about how to set it up.
So this is really a matter what you would like to achieve. My case was to get this thing running with mobile and a One-Page-App JavaScript.
Basically all you need to do is generate some kind of header that value that will be needed in every consecutive request you client will make.
So you do a endpoint in which you wait for a post with user/password:
#Path("/login")
public class AuthenticationResource {
#POST
#Consumes("application/json")
public Response authenticate(Credentials credential) {
boolean canBeLoggedIn = (...check in your DB or anywher you need to)
if (canBeLoggedIn) {
UUID uuid = UUID.randomUUID();
Token token = new Token();
token.setToken(uuid.toString());
//save your token with associated with user
(...)
return Response.ok(token).type(MediaType.APPLICATION_JSON_TYPE).build();
} else {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
}
Now you need to secure resource with need for that token:
#Path("/payment")
#AuthorizedWithToken
public class Payments {
#GET
#Produces("application/json")
public Response sync() {
(...)
}
}
Notice the #AuthorizedWithToken annotation. This annotaation you can create on your own using special meta annotation #NameBinding
#NameBinding
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface AuthorizedWithToken {}
And now for the filter that implements checking of the header:
#AuthorizedWithToken
#Provider
public class XAuthTokenFilter implements ContainerRequestFilter {
private static String X_Auth_Token = "X-Auth-Token";
#Override
public void filter(ContainerRequestContext crc) throws IOException {
String headerValue = crc.getHeaderString(X_Auth_Token);
if (headerValue == null) {
crc.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Missing " + X_Auth_Token + " value").build());
return;
}
if(! TOKEN_FOUND_IN_DB) {
crc.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Wrong " + X_Auth_Token + " value").build());
return;
}
}
}
You can create any number of your own annotations checking for various things in the http request and mix them. However you need to pay attention to Priorities but that actually easy thing to find. This method needs using https but that is obvious.
Security comes in two main flavours :
Container Based
application based
the standard way to secure spring applications is to use Spring Security (formerly Acegi).
It would be interesting to know why you're not being allowed to use that.
You could use container based security, but I'm guessing that your use of spring precludes that option too.
Since the choice of Spring is usually to obviate the need for the use of a full J2EE container (Edit : though as pointed out below by others, most ordinary servlet containers do allow you to implement various container based security methods)
This really only leaves you with one option which is to roll your own security.
Your use of Jersey suggests that this might be a REST application.
In which case you really ought to stick with standard HTTP Authentication methods that
comes in the following flavours in reverse order of strength :
BASIC
Digest
Form
Certificate
REST applications are usually supposed to be 'stateless', which essentially rules out form based authentication (because you'd require the use of Session)
leaving you with BASIC, Digest and Certificate.
Your next question is, who am I authenticating. If you can expect to know the username AND the password of the user based on what URL they requested (say if it's one set of credentials for all users) then Digest is the best bet since the password is never sent, only a hash.
If you cannot know the Password (because you ask a third party system to validate it etc.) then you are stuck with BASIC.
But you can enhance the security of BASIC by using SSL, or better yet, combining BASIC with client certificate authentication.
In fact BASIC authentication over HTTPS is the standard technique for securing most REST applications.
You can easily implement a Servlet Filter that looks for the Authentication Header and validates the credentials yourself.
There are many examples of such filters, it's a single self contained class file.
If no credentials are found the filter returns 401 passing a prompt for basic auth in the response headers.
If the credentials are invalid you return 403.
App security is almost an entire career in itself, but I hope this helps.
As the former posts say, you could go with different options, with a varying overhead for implementation. From a practical view, if you're going to start with this and are looking for a comfortable way for a simple implementation, I'd recommend container-based option using BASIC authentication.
If you use tomcat, you can setup a realm, which is relatively simple to implement. You could use JDBCRealm, which gets you a user and password from specified columns in your database, and configure it via server.xml and web.xml.
This will prompt you for credentials automatically, everytime you are trying to access your application. You don't have any application-side implementation to do for that.
What I can tell you now is that you already did most of the 'dirty' job integrating Jersey with Spring. I recommend to you to go an Application-based solution, is it does not tie you to a particular container. Spring Security can be intimidating at first, but then when you tame the beast, you see it was actually a friendly puppy.
The fact is that Spring Security is hugely customizable, just by implementing their interfaces. And there is a lot of documentation and support. Plus, you already have a Spring based application.
As all you seek is guidance, I can provide you with some tutorials. You can take advantage from this blog.
http://www.baeldung.com/rest-with-spring-series/
http://www.baeldung.com/2011/10/31/securing-a-restful-web-service-with-spring-security-3-1-part-3/

dynamic proxy soap web service client in java?

Is there any way to use soap-rpc web services such that the client is generated via a shared interface? Restful web services do it this way, but what about soap based? Do you always have to use a tool like Axis or CXF to generate your stubs and proxies, or is there something out there that will set it up dynamically?
Thanks.
EDIT #1:
To clarify, I'm looking to do something like this:
Common interface:
#WebService
public interface MyWebService {
#WebMethod
String helloWorld();
}
This common interface can already be used to create the server side component. My question is: can this type of common interface be used on the client side to generate dynamic proxies? Restful web services do it this way (Restlets & CXF) and it seems the .Net world has this type of functionality too.
I would see this tutorial of JAX-WS useful for your purposes:
In the example code the Web Services Client is configured by adding an annotation #WebServiceRef with a property pointing to the WSDL location to the client implementation class and no tools are needed to access the stuff from the Web Service that is referenced.
Was this the way you would like to have it, or did this even answer to right question?
Not exactly sure what you're looking for, but if you don't want to rely on JAX-WS/JAXB-generated artifacts (service interfaces and binding objects), you can make use of the Service and Dispatch APIs. For example:
QName serviceName = new QName(...);
Service service = Service.create(serviceName);
QName portName = new QName(...);
String endpointAddress = "...";
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
SOAPMessage request = ...;
SOAPMessage response = dispatch.invoke(request);
Check Apache CXF. Configuring a Spring Client (Option 1).
When you want to call a webservice, you must have knowledge of methods implemented on it. For that, We need to make stubs OR we can read it from WSDL.
I have created a WS client, using AXIS2 libraries, which is without stubs. The thing is, for each diff. WS we need to create response handles.
You can call any WS method using SOAP envelops and handle the response.
//common interface for response handlers...
//implement this for diff. web service/methods
public interface WSRespHandler{
public Object getMeResp(Object respData);
}
//pass particular handler to client when you call some WS
public class WebServiceClient {
public Object getResp(WSRespHandler respHandler) {
...
return repHandler.getMeResp(xmlData);
}
}
Please check the link below, which shows the example interface for WS client.
http://javalibs.blogspot.com/2010/05/axis2-web-service-client-without.html
For every diff. WS method we can have diff. implementation for WSRespHandler interface, which will help parsing the response.
Not knowing java so well, but being forced to learn some to accomplish a task that I was given, I needed to consume a .Net service that I have already written, I had to do a little research.
I found that 99% of the examples/samples/problems with invoking a method call against a .Net service, or any service for that matter involved using J2EE (ServiceManager) or build classes and a proxy that reflect the service being invoked. Unfortunately for me, none of this would work. I was working "in a box". I could not add new classes, could not WSDL references, did not have J2EE, but DID have access to the standard java libs.
I am used to doing this sort of thing in pretty much every other language but java, but now there was no choice, and java it was.
A lot of digging and figuring out all new terminology, methods, classes, etc, I knew I was getting close, but was having issues with some small items to complete the task.
Then I came across this post: http://www.ibm.com/developerworks/xml/library/x-jaxmsoap/
As long as you have some sort of idea of what you need to send the soap service in term of the soap envelope, the above link will give you the information you need to be able to invoke a service without the classes, wsdl class generators and J2EE, apache or other dependencies.
In an hour from the time I read the mentioned article, I had a class working and about 10 minutes later, converted the code to the "in the box" solution.
Hope this helps
Apache Tuscany might help you, although it may be heavier than you want
http://tuscany.apache.org/

Simple Java stand-alone server container/framework?

For the last couple of years I've had my head in Python, where there are numerous choices for simple, minimal frameworks that allow me to stand up a website or service easily (eg. web.py). I'm looking for something similar in Java.
What is the simplest, least-moving-parts way of standing up simple services using Java these days? I'm looking for something as simple as:
the ability to receive HTTP requests
the ability to dispatch those requests to handlers (preferably a regular expression based url to handler mapping facility)
the ability to set HTTP headers and generally fully control the request/response
Bonus points if the framework plays well with Jython.
[Update] Thanks for the responses, some of these look quite interesting. I'm not seeing the url dispatch capability in these, however. I'm looking for something similar to Django's url.py system, which looks like:
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
Where you specify a url regular expression along with the handler that handles it.
I liked to worth the Simple HTTP Server from the Simple Framework. It offers a nice Tutorial about how to start as well.
there are several alternatives:
servlets
restlet: lightweight REST framework
jax-rs: using jersey or the restlet module implementing the jax-rs specs
grizzly: NIO based server (with HTTP support + handlers)
apache mina: event-driven, async server (with HTTP support)
all these frameworks come with a built-in server.
EDIT
jax-rs has a similar approach using url templates:
#Path("/users/{username}")
public class UserResource {
#GET
#Produces("text/xml")
public String getUser(#PathParam("username") String userName) {
}
}
then put your handlers in an Application object:
public class MyApplicaton extends Application {
public Set<Class> getClasses() {
Set<Class> s = new HashSet<Class>();
s.add(UserResource.class);
return s;
}
}
another example with JAX-RS:
#GET
#Produces("application/json")
#Path("/network/{id: [0-9]+}/{nid}")
public User getUserByNID(#PathParam("id") int id, #PathParam("nid") String nid) {
}
EDIT 2
Restlet supports a centralized configurations like Django, in your Application object:
// Attach the handlers to the root router
router.attach("/users/{user}", account);
router.attach("/users/{user}/orders", orders);
router.attach("/users/{user}/orders/{order}", order);
Servlets might be the way to go. To do very simple things you only need to override one method of one class. More complicated stuff is of course possible, but you can go a long way with a little work.
Investigate Tomcat or Jetty - both are open source and well supported.
public class HelloWorldServlet extends HttpServlet {
public void doGet( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException
{
response.setContentType( "text/plain" );
PrintWriter out = response.getWriter();
out.print( "hello world!" );
}
}
Note: This is more general discussion than answer.
I'm having similar issues coming from Python for 10+ years and diving, as it were, back into Java. I think one thing I'm learning is that the "simplicity" factor of Python is very different from that of Java. Where Python abounds with high-level framework-- things like web.py, Java seems much more lower level. Over the past few months, I've gone from saying "What's the Java way to do this easy in Python thing" to "How does one build up this thing in Java." Subtle, but seems to bring my thoughts around from a Python-centric view to a more Java-centric one.
Having done that, I've realized that standing up a website or service is not simple for a Java outsider, that's because there's a large amount of info I have to (re)grok. It's not as simple as python. You still need a webserver, you need to build a "container" to drop your Java code into, and then you need the Java code (am I wrong on this, everyone? Is there a simpler way?).
For me, working with Scala and Lift has helped- and not even those, but this one thread by David Pollack. This was what I needed to build a Jetty server. Take that, follow the directions (somewhat vague, but might be good enough for you) and then you have a servlet container ready to accept incoming traffic on a port (or 3 ports, in his case). Then you can write some Java code using HTTPServlet or something to go the rest of the way.
Again, this is just what I did to get past that barrier, but I'm still not a Java guru. Good luck.
I've hard about: Apache Mina
But quite frankly I don't even know if it is what you need.
:-/
:)
Jetty is a pretty nice embedded http server - even if it isn't possible to do the mapping like you describe, it should be pretty easy to implement what you are going for.

Categories

Resources