Java app secured by KERBEROS - java

I would like to secure my Java web app by KERBEROS. Do anyone know what is required to do that and how much I would have to change my app if my current users are stored in MySQL database? Is necessary to use VPN? If I undersatnd right, each of clients authenticate over KDS in same domain, but my app is on remote server (not in same domain?).

You have to give us more details about the your app and your environment. What kerberos does, it provides the way for the user to prove that he is indeed who he claims he is. Optionally you can verify that he is coming from IP address that he is claiming to come from, although later is rarely users due to NAT / Proxies / Load balancers.
What container does your app run in? Most of the modern servlet containers ( JBoss / Websphere ) provide kerberos authentication out of the box. You just need to adjust your web.xml or in case of websphere just configure the app correctly.
Do you have kerberos infrastructure in place? If you are in enterprise windows environment with an Active Directory domain controller you already do. In this case you need to configure workstations to be on the domain. The simplest case is if your workstations are members of the domain and the active directory controller is also your DNS server, and your application is running in the local domain and your browser is IE or Chrome. Otherwise you need to do some extra configuration.
The VPN is not necessary, although if you have one it will simplify things a bit.
As for your domain question there is a lot of confusion especially with Windows admins over what domain actually is. Domain could be DNS domain like stackoverflow.com and domain could be active directory domain which is something completely deifferent. In classical Unix kerberos the kerberos domain is called REALM and there is a configuration file that maps DNS domains to Kerberos realms.
Your app could be in any DNS domain you want, it could be in any Active Directory domain also, but in this case there must be a trust relationship established between different domains.
The bottom line is, as a bare minimum you have to configure two things. The DNS server must have SRV records so that the browser could find the KDC server. And you have to register your app in the KDC.
For more details google look here :

Related

Dynamically generated SSL sites

I am building a system on AWS for my client. The client's customers will be able to access a login page and create their own EC2 instance. This EC2 instance will be pre configured with Tomcat and my client's war file auto deployed. The users will be able to access the web application from the ip address. For e.g. Lets say User A logs onto a portal. Clicks on create instance. An instance gets auto provisioned with a URL (like http://18.xx.xx.xx/MyApplication). User A will be able to do a whole bunch of activities on this web site.
Now, is there any way that I can dynamically enable SSL on these. I would need to generate SSL certificates on the fly and attach it to the URL. Ideally UserA should be able to access https://18.xx.xx.xx/MyApplication. Self signed certificates will not cut the ice. This might be rudimentary, but I have limited knowledge on SSL. Any help/tips/links to URLs would be greatly appreciated.
For additional clarity - these instances will not be clustered. User A will have his own instance and his own application. User B will have his own instance and his own application. User A and User B's instances will not be clustered. I need to ensure that User A's instance when created has SSL enabled automatically.
Cheers!
VJ
You may want to setup a DNS with hostnames for each instance. Maybe hostnames like 18-xxx-xxx-xxx.yourdomain.com where "18-xxx-xxx-xxx" is the IP address with - instead of ..
For such hostnames you can generate and renew Let's Encrypt certificates programatically. There exist programs in standard linux repos for generating Let's Encrypt certificates. You cannot generate certificates for IPs. That's why you have to setup hostnames in the first place.
Now you just have to setup the certificate for your Tomcat (programatically).
There's several solutions from AWS that can work for this case, revolving around CloudFormation specifically.
For pre-configured Tomcat and WAR file, and even application, you can create a custom AMI.
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html
For each deployment, you can use a CloudFormation template to automate provisioning of this AMI.
For SSL, with some CloudFormation templating, you can include an AWS ALB that listens on HTTPS and targets the new server on each deployment. Also, you can provision the new certificate and attach it to the LB.
Here's the useful links:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-certificatemanager-certificate.html
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticloadbalancingv2-listener-certificates.html

How to send sensitive data to a Liferay portlet from outside the Liferay portal

I've got a Liferay Portal (6.2 CE) with some Portlets (let's say Portlet A and Portlet B)
I'll be called from outside the portal (a third party from the internet) with some params (http://myUrl/myPath?param=X&email=myUser#email.address&info=moreUserPersonalData), and depending of the value of one of those params I need to display one or another portlet. Following the example, if param=A, go to portal page with Portlet A; if param=B, go to portal page with Portlet B.
Some of the params will be sensitive data and I need them to reach the final portlet A or B.
So, I've got different doubts...
Wherever I'll be called, I can decide its technology. I've managed:
A servlet. The main problem is that I cannot share the session between the Servlet and the Portlet, so I can't set there the params. I don't want to send it by GET (it's personal information) and any way to avoid that (like ciphering the data or saving temporarily in a database) looks too much complicated for such a simple task.
A landing portlet. I need to make the redirect with no user action needed, so the lifecycle of a portlet doesn't help me. The render phase (the one called when I land there) doesn't have the redirect method (looks like it goes against liferay's portlets politics) and I don't want to make a javascript autosubmit to reach the action phase.
So, in summary, I need to:
Be called from a third party
Manage some of the data sent by that third party
Redirect to a portlet, sending sensitive data not seen at the url
Decide the better technology to do that
Can you give me any suggestion?
Thanks in advance.
Secure IPC in Liferay
This is mostly a placeholder until you clarify your requirements and functional specifications. I am going to present some security essentials related to the Liferay platform and associated technologies. I will make the advice as general as possible however full disclosure the bulk of my experience is 6.2 EE.
Proposed solution
I think the most obvious way to do this is to have one, or many, web services exposed to clients outside the portal. I would suggest you stay away from trying to accept all the data into a single web service and then routing it accordingly. Instead I suggest you create a web service for every particular end point (wherever you are routing data to) and call that point directly. Your client should be configured to send the data to the appropriate place. However, if for whatever reason you absolutely need to have a single end point to call, then I would suggest you create that end point by registering a jsonws through service builder and then using Liferays internal Spring AMQP bus to route the message accordingly.
To register a JSON WS simply create a service builder entry as follows:
<entity name="Entity" remote-service="true" local-service="true">
In your JSR-286 Portlet that will create the following modifiable files
EntityLocalServiceImpl.java
EntityServiceImpl.java
EntityImp.java
Your EntityServiceImpl file will generate code in EntityService (which will be the service you invoke externally). I generally suggest in EntityServiceImpl you write code that has to do with Liferay's permission checking / resource framework, and once that is successful you then call a method by the same name in the EntityLocalServiceImpl method. The local service method alone should be where you write to the message queue or database.
To invoke your web service you can reference the million Liferay documents online related to JSONWS. Is is just a brief architectural overview, but I have general hardening steps for the entire stack below.
Liferya Tech Stack Hardening
Let's talk about how you currently have your portal configured. I am going to assume you are running one or many Tomcat application containers behind an Apache web server. However, if you are not running these specific technologies, the advice I am giving is interchangeable.
1. Portal Version
Make sure you are at least running the Enterprise Edition at 6.2 or DXP. Verify that your portal is at the most recent batch level for that release branch. I would suggest you go even further and make sure that you have every single hotfix as well (you can be at the highest patched version but still missing a hotfix).
2. Portal Installation and OS
I would suggest your harden your Tomcat server / portal installation by doing the following things.
Install inside a chroot jail.
Owner and group should be a non root user
Run your Tomcat instance with Java security manager, develop a java policy file specific to the needs of that Tomcat instance.
Enable, correctly configure, AND ENFORCE SSL at the Tomcat layer
Override all the default error pages (404, etc). Create a new page to display for any page that returns a java.lang.Exception
Protect your shutdown port
Make sure tomcat doesn't server index pages when welcome page's arent specific.
Changer permission bits on your portal_home/conf folder to 400/read only.
Remove server version in HTTP response headers
Strip and repackage ServerInfo.properties in the catalina jar.
Set secure flag for cookies
Add HTTPOnly for cookies
Make sure that you have iptables or some other firewall that closes all ports from the outside. SSH only from the inside. Only enable port 80 from outside (if its public facing) and drop the rest.
Deactivate the JSP deployment engine
3. Web Server layer
The web server layer will have general security measures similar to your Tomcat instance. It may be much more difficult to run your web server in a chroot jail or with a non privileged account though. It would be nice to have a real, enterprise IPS sitting in front of your web server (or load balancer if one exists).
Enable and properly configure SSL (for best security do this at the app container and web server layer). Disable ssl v2, v3, etc. This topic is way to big for a single bullet point
Remove information gathering abilities by removing/disabling ETag, directory listing pages, server name response headers,
Run your web server from an apache user with apache group (or whatever account you choose). You can attempt to make this a non privileged account but again it might be difficult.
Change the permission bits on the configuration folder to 750
Limit what type of Request methods you want to allow here (you can disable request methods like put, post, etc here). What do you obviously will determine how you configure this
Disable http 1.0
Disable trace requests
Set set your httponly and secure flag for cookies at this layer as well
Enable protection against click jacking, xss, etc.
4. Liferay properties hardening
There are several properties that you can toggle to harden your Liferay platform. Some very obvious ones (and their descriptions):
Always keep the following two enabled
auth.token.check.enabled=true
json.service.auth.token.enabled=true
This relates to the p_auth get parameter you will see in the portal. The client is responsible for generating this token. If your client is outside the portal environment.
If your client is outside the portal environment you can ignore tokens for particular origins
auth.token.ignore.origins=.....
Basically this will allow you to ignore the auth token requirements for particular origins. This is much better than ignoring for all.
I would definitely suggest you forcing HSTS and again filtering based on request methods
jsonws.web.service.strict.http.method=true
jsonws.web.service.invalid.http.methods=DELETE,POST,PUT
# Not necessarily filtering the above methods just an example
To secure the webservice I would likely require basic authentication
basic.auth.password.required=true
With basic authentication you also need to make the specific web service endpoint public
jsonws.web.service.public.methods=.....
Then a this point you need to configure basic authentication and user account on your tomcat/web server.
I would further restrict access to the jsonws page, servlet, and services by using
son.servlet.hosts.allowed=....
json.servlet.https.required=true
jsonws.servlet.hosts.allowed=....
jsonws.servlet.https.required=true
You might also want to check out the AccessControlled annotation
For basic authentication done right you need to look at the authentication pipeline examples.
4. Additional Liferay hardening
In addition to securing the web service I would probably secure your portal by:
Disabling the default administrator account using the default.admin.*properties,
Block the following pages
/c/
/api/
/usr/
/group/
Disable all the default portlets by filtering based on p_p_id
Seriously consider restricting WebDAV Servlet, Spring Remoting Servlet, Liferay Tunneling servlet, Axis Servlet.
Disabling unwanted/unused struts actions
Use JNDI of JDBC
I realize this is basically just a big dump of information without much context but when talking this broadly about security its all applicable. I didn't even touch the data layer because you didnt mention persistence. StackOverflow is more helpful when you do the preliminary research, try to implement a solution, and run into a very particular problem. Hopefully this will put you in the right direction to a more pointed question
Create a website made with SSL/TLS security encryption.

Providing LDAP support on top of existing Database authentication

I am working on a java application having Database authentication using spring-security.
It is very usual that, this application is used with other applications on similar domain.
Requirement: The need is that all such partner apps should be able to share common authentication with my application.
Also it is required to continue supporting DB authentication as well.
One way I found is to embed LDAP server like ApacheDS in my application so that other partner apps can use it to get authenticated.
In this case, I need to load ApacheDS with related Database records and keep it in sync programmatically.
But disadvantage on this is to have redundant copy of authentication data - one at DB and another at ApacheDS LDAP.
Question: Is there any way to avoid such duplication. By googling, I found option of having virtual directory server Penrose or Oracle Virtual Directory. But unfortunately they cannot be embedded in application. Is there any way to provide embedded LDAP support on top of existing Database authentication?
Disclaimer: I know very little about Spring Framework and even less of Spring Security
Having said that. I did face a similar situation, in my case, it was Apache DS as my app authentication source and client AD as the other.
My deployment environment was Tomcat and I used Tomcat Combined realm, which nests more than one realm for authentication. My app realm was configured to be one and client's AD was configured to be another.
Users could authenticate from any one of the realm, it worked. However, I did have to replicate client's AD users every night (including AD tombstones to mark them inactive), for authentication is one thing but other client information was also required, e.g. email, roles etc. and inclusion of new users.
I am kind of sure that Spring Security will also have the concept of Combined Realm.
I understand that this answer is not really an answer and more of design approach and many years too late at that; however, I wished to share my experience.

webservice authentication - do I need SSL?

I have a question about whether I really need SSL or not. The scenario is as follows:
I have two applications at the moment, they are both Java webapps. One of them is getting data from another via RESTful web service secured by Spring Security, but my problem is that it sends username and password in URL so the other app can authenticate and authorize it using LDAP. In the end both apps will be running on JBoss AS 7 server so even though one of them is a client and the other one is server they will be running on one server and that confuses me a little bit (even if they will use multiple instances of JBoss they will still be both in the same network). Also signing certificate by third party seems unnecessary here because I don't really care if anyone will trust my server app and again I found that I can implement my own Certificate Authority but it really seems to me as an overkill.
So to summarize it: if I only care about request (or just its parts - username and password) being encrypted do I need to enable SSL and provide all it needs or is there any easier way to achieve it?

Intercepting an LDAP in order to gather statistics

We are looking at building an application that either proxies a standalone LDAP server or delegates to an embedded Java LDAP instance (ie: ApacheDS, OpenDS) in order to log requests and determine who is accessing which applications on our very large corporate network.
My question is is there a good way to intercept an LDAP request and "pull it apart" or have either OpenDS/ApacheDS push notifications of requests coming into LDAP.
You don't need to do any of that. You can configure LDAP servers to log accesses, either in the LDAP directory itself or elsewhere.
OpenDJ (the actively developed fork of OpenDS, http://opendj.forgerock.org) has support for multiple and customized access logs, so you can even configure some filters for the specific requests you're interested in.

Categories

Resources