Best practise to apply HTTPS for Webservice - web-services

Im working on the developpment of webservices in JAVA implemented with CXF 2.5.2.
Im using apache Tomcat as web server.
I need to add HTTPS Security in some webservice method, i would like to know the best to implement HTTPS Security.
I heard that I can configure HTTPS in web.xml by specifing security constraint...or I can configure HTTPS in Apache tomcat for any method.
My ideas about advantage and disadvantage about each solution,
I think the advantage to configure https in web.xml is to localize in the same webapp of webservice.
The advantage in apache tomcat configuration let to not be coupled to any webapp.
Iam sure there is more way to implement HTTPS.
Thank you !

Configuring security in web.xml ( for example )
<security-constraint>
<web-resource-collection>
<web-resource-name>REST Service </web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>User</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Test</realm-name>
</login-config>
<security-role>
<role-name>User</role-name>
</security-role>

Related

Getting 403 Forbidden, trying to access secured web service

Has anyone successfully secured a web service using Active Directory credentials instead of an application specific username/password?
I have an application that talks to web services written with Axis2 1.5.1 and deployed on Tomcat 6.0.24, deployed on Linux, FWIW.
I have changed Tomcat from a JDBCRealm, authenticating against a database, to a JAASRealm, configured to access AD with Centrify (the client's preferred solution).
This works with web applications but for web services I get a 403 response.
I have tested using a simple Axis2 service (written with Axis2 1.5.1) and deployed against Tomcat 6.0.24 and 7.0.63. I've also tried with a web service written using Axis2 1.6.2. I get the same result in each case. I'm testing using a browser, BTW. When the service works I get xml; when it doesn't I get the error.
I'm wondering whether I need to change something in axis2.xml since even https://tomcat:8443/HelloWorld (my service is called HelloWorld) generates a 403.
Some configuration details...
I've changed the realm in server.xml to the following
<Realm className="org.apache.catalina.realm.JAASRealm"
appName="CENTRIFYDC"
roleClassName="com.centrify.dc.tomcat.RolesPrincipal"
userClassName="com.centrify.dc.tomcat.LoginPrincipal" />
<Valve className="com.centrify.dc.tomcat.ContextValve" />
In web.xml I have added
<security-constraint>
<display-name>Security Web Service</display-name>
<web-resource-collection>
<web-resource-name>Secured Area</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>USER</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>SPNEGO</auth-method>
<realm-name>CENTRIFYDC</realm-name>
</login-config>
<!-- Security roles referenced by this web application -->
<security-role>
<role-name>USER</role-name>
</security-role>
I've mapped the USER role to one of my AD groups
Any suggestions or guidance or setups that have worked for someone would be very useful, thanks.
The 403 error is indicating the permission problem after authentication. It is because after SSO, the server will check for group membership to see if the user got proper permission. The 403 error is coming from the configuration part of role mapping. SSO to the server is actually working fine.
We would suggest you to try the following(the following example is using 5.5 version tomcat but it will be the same for later version):
Configure tomcat for Centrify
a. Configure tomcat for Centrify by using configure.pl:
cd /usr/share/centrifydc/java
./configure.pl
Enter /opt/apache-tomcat-5.5.25 when prompted for the tomcat directory.
Enter /usr/jdk1.5.0_15 when prompted for the java directory.
Enter y when prompted if you want to configure Tomcat for SSL
Enter n when prompted if you want to configure Tomcat for SSL communication with ADFS server
Take default for everything else.
Configure webdav for Centrify and use kerberos(SPNEGO) for authentication
a. Set the logon realm to CENTRIFYDC:
cd /opt/apache-tomcat-5.5.25/webapps/
mkdir webdav/META-INF
create webdav/META-INF/context.xml as:
<Context path="/webdav">
<Realm className="org.apache.catalina.realm.JAASRealm"
appName="CENTRIFYDC"
roleClassNames="com.centrify.dc.tomcat.RolesPrincipal"
userClassNames="com.centrify.dc.tomcat.LoginPrincipal"/>
<Valve className="com.centrify.dc.tomcat.ContextValve"/> </Context>
b. Configure mapping of AD groups to roles for the jspwiki app.
cp /usr/share/centrifydc/java/templates/centrifydc.xml webdev/WEB-INF/centrifydc.xml
modify RoleMapping section in webdev/WEB-INF/centrifydc.xml as follow:
<RoleMapping separator=";">
<Role name="user" group="*" user="*"/>
<Role name="#ROLE2#" group="#GROUP2#"/>
<Role name="#ROLE3#" user="#USER3#"/>
</RoleMapping>
c. Configure web.xml to use kerberos(SPNEGO) for authentication:
Edit web.xml and add
<login-config>
<auth-method>SPNEGO</auth-method>
<realm-name>Default</realm-name>
</login-config>
<!--
OPTIONAL: Add CentrifyFilter to set the authenticated user's attributes
such as group membership in HTTP headers. You must also configure the
<SetHeaders> element in centrifydc.xml to set user attributes in HTTP
headers.
This filter is not needed if you do not want the authenticated
user's attributes set in HTTP headers.
-->
<filter>
<filter-name>CentrifyFilter</filter-name>
<filter-class>com.centrify.dc.wbase.DCFilter</filter-class>
</filter>
<!--
OPTIONAL: Apply (map) CentrifyFilter to the url patterns in the
<security-constraint> section of this application to set the
authenticated user's attributes in HTTP headers.
This <filter-mapping> is not needed if you do not want the
authenticated user's attributes set in HTTP headers.
-->
<filter-mapping>
<filter-name>CentrifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>ProtectedResource</web-resource-name>
<url-pattern>/index.html</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<description>
An test role
</description>
<role-name>user</role-name>
</security-role>
You could also refer to the Centrify Java Guide p.135 for the example for role mapping configured as follow:
Extensible Markup Language (XML) files, like the centrifydc.xml file, are structured documents that contain a set of supported elements enclosed in opening and closing angle (< >) brackets. The elements can be required or optional depending on the requirements of the application. The following is an example of how the key elements defined in the centrifydc.xml file:
<Centrifydc>
<enableAuthSchemes>Negotiate,NTLM,Basic</enableAuthSchemes>
<adclientSocket>/var/centrifydc/daemon</adclientSocket>
<RoleMapping>
<Role name=”role1” group=”arcade.com/Users/Sales”/>
</RoleMapping>
</Centrifydc>
Although the template centrifydc.xml file contains some default settings, these default settings should be modified in the copy of the centrifydc.xml file you place in an application’s WEB-INF directory. The following table describes the elements you can set in the centrifydc.xml file.
If you need any further assistance, please feel free to contact Centrify Technical Support directly.
There were a couple of problems. The first was an error was in the server.xml file. JAASRealms can accept several classes for role and user so the properties are roleClassNames and userClassNames as follows
<Realm className="org.apache.catalina.realm.JAASRealm"
appName="CENTRIFYDC"
roleClassNames="com.centrify.dc.tomcat.RolesPrincipal"
userClassNames="com.centrify.dc.tomcat.LoginPrincipal" />
The second issue is around using several applications which use different authorization. The centrifydc.xml file maps roles when the app is first authenticated. However, if org.apache.catalina.authenticator.SingleSignOn is enabled then the roles are set only for the application that performs the authentication. Thereafter, only the roles set in the authenticating application's centrifydc.xml file are set. Other applications will see that the user is already authenticated but does not have the necessary authorization and fail with a 403 error.
In different applications use the roles user, USER and manager then the logging-in application must set up all three roles when it authenticates.

Configure http basic auth on EJB web service in Wildfly

I work with Glassfish and in glassfish-ejb-jar.xml I'm able to secure ejb exposed web service like this (http basic auth)
<ejb>
<ejb-name>Command</ejb-name>
<webservice-endpoint>
<port-component-name>Command</port-component-name>
<endpoint-address-uri>NPI/command</endpoint-address-uri>
<login-config>
<auth-method>BASIC</auth-method>
<realm>NPI</realm>
</login-config>
</webservice-endpoint>
</ejb>
I'm looking for a similar way to do it when deploying to Wildfly but so far I wasn't able to find a solution.
All I have found is a description how to do it in web.xml but I guess that asks for web services to be exposed via servlet cointainer.
Are there any Wildfly specific deployment descriptors or methods to get the same results as with glassfish ejb descriptor on glassfish server?

Implementing ssl on glassfish 4.0 on localhost

I am using a glassfish server and implementing Rest webservices which can be consumed from web or mobile clients.
I now want to secure these webservices using ssl certificates and create a session between client and server. I have not yet purchased any domain name or server space and trying to build it on my local machine.
How do i configure a free ssl certificate for glassfish on my localhost.
Thanks,
Pavan
Hotcoder24,
As far as I understand the problem from your question and comment, you want to communicate with your service via HTTPS. This is a snap when you use an application server. In fact, this is done with configuration in your web.xml file.
Let's start with a simple web application created using maven archetype jersey-quickstart-webapp, described in Jersey tutorial.
mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-webapp -DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false -DgroupId=com.example -DartifactId=simple-service-webapp -Dpackage=com.example -DarchetypeVersion=2.14
This creates a web application containing a single resource, which can be deployed to a Glassfish server (a war-file is produced).
#Path("myresource")
public class MyResource {
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* #return String that will be returned as a text/plain response.
*/
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getIt() {
return "Got it!";
}
}
First of all, you should create a user and add it to a group using Glassfish console (http://localhost:4848/). The simplest way to start is to use a file realm. The process is described here. Let's create a user called “user” and group called “users”.
If you deploy the application, the resource will be available in your browser if you enter a URL http://localhost:8080/simple-service-webapp/webapi/myresource. Before we have done any configuration in the project's xml files, the resource is freely available.
Now let's add some elements to your web.xml file.
<web-app 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">
<!--Some elements go here-->
<security-constraint>
<web-resource-collection>
<web-resource-name>GetIt</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>users</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>file</realm-name>
</login-config>
<security-role>
<role-name>users</role-name>
</security-role>
We added tree elements:
security-constraint which describes a URL pattern to protect, lists roles allowed to access it and most important to your question is the user-data-constraint element, which in our case switches on the HTTPS.
login-config element instructs the server to use the simplest authenticated mechanism which means, that when you try to access the resource using a browser, a dialog prompting for login and password is displayed to you; also you realm's name is enshrined here;
the last element defines roles you use.
Now it is necessary that groups are linked to roles. This is done using a container-specific glassfish-web.xml.
<glassfish-web-app error-url="">
<security-role-mapping>
<role-name>users</role-name>
<group-name>users</group-name>
</security-role-mapping>
<!--some elements go here-->
Now if you direct your browser to a http:// URL, you'll be switched to https://, which is not the case without the user-data-constraint element with <transport-guarantee>CONFIDENTIAL</transport-guarantee>.

Exposing WebService on Mule

I wanted expose an WebService on mule and its working.
My concern is that am not sure if this is the right approach to follow in exposing a webservice.
As I wanted to be able to view my Mule HTTP Inbound endpoint wsdl i.e
XXX:8084/HelloService?wsdl
, notice the actual service is running on port 8085.
<flow name="WS_In" doc:name="WS_In">
<http:inbound-endpoint address="http://localhost:8084/HelloService" exchange-pattern="request-response" doc:name="HTTP">
<cxf:proxy-service wsdlLocation="http://localhost:8085/HelloService?WSDL" payload="envelope" namespace="http://example.org/HelloService" service="Hello"/>
</http:inbound-endpoint>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8085" doc:name="HTTP" path="test"/>
</flow>
So you're not exposing a service but just proxying it right?
Why not using the ready made pattern for that? See: http://www.mulesoft.org/documentation/display/current/Web+Service+Proxy+Pattern
Proxying web services is a very common practice used for different reasons like security or auditing. This pattern allows a short and easy configuration of such a proxy.
With this you can
Transform the SOAP envelope (body or header) to add or remove specific entries.
Rewrite remote WSDLs so they appear to bind to services inside a corporate firewall.
Mule has already defined these proxy transformers in various ways:
Ref: https://docs.mulesoft.com/mule-user-guide/v/3.7/web-service-proxy-pattern#wsdl-redirection

Enable https for java ejb Webservice

i'm developing a webservice with ejb 3 and glassfish 3.1.1. I'm using Netbeans 7.0 and would like to know, how to enable https on port 8181 for this webservice.
I dont need any authentication method, just secure the communication through https!
Thx
Adem
You need to specify a secure connection as explained here. Essentially, in your deployment descriptor web.xml you need to set:
<security-constraint>
...
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
However NetBeans will insert the code for you: open web.xml, click the Security tab along the top of the editor, then click the Add Security Constraint button. Type a name, in URL pattern write /*, set All Http Methods, and specify Confidential as Transport Guarantee.
If you don't have web.xml, because you are deploying just the Enterprise Java Bean, create a New GlassFish Descriptor glassfish-ejb-jar.xml and fill it like this (or see here the file hierarchy):
<glassfish-ejb-jar>
<enterprise-beans>
<ejb>
<ejb-name>Hello</ejb-name>
<webservice-endpoint>
<port-component-name>Hello</port-component-name>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</webservice-endpoint>
</ejb>
</enterprise-beans>/>
</glassfish-ejb-jar>
Your application will use port 8181 from now on.
See here for further information about how to setup security in a Netbeans web application and here for learning about certificates.