I'm in the process of writing a server application that mainly allows people to submit jobs to a DRM system (e.g. TORQUE) over RMI. The application needs to run as root so that it can submit proxy jobs (where a job is run as a user other than the user who submits it), however this obviously isn't secure - the user name is simply a string parameter in the RMI. Anyone could pass any user name in and have a job run as that user.
What's the best way to get Java to authenticate this user name against authorised users of the system (with the aid of a password that would also be passed in)? I've had a look at JAAS and Apache Shiro, but they seem to be all about creating your own authentication methods. I want to use the system's existing authentication methods (Unix-like system), whatever they happen to be. Essentially if the user can SSH in, they're all right.
If your backend uses LDAP (which is possible if you have to manage a relatively large number of users for which a local /etc/passwd might be tedious), you can use JAAS and the existing LdapLoginModule.
If you want to authenticate against you local system (assuming Linux server) without this, it looks like JAAS-PAM might be able to help, although I've never tried it.
Related
I need to develop a web application for the Intranet users. I don't want them to enter the login credentials each time they visit the site. It should be automatically loaded from the System Username and Password.
I have successfully implemented functionality which prompt user name and password registered with active directory and validate against LDAP. I need some tips to login directly from intranet website without prompt username & password.
Here is my queries, please let me know your suggestion.
Is it compulsory to set SPN?
Do we need to create separate keytab file for each client? In my organization, there is around 800 people are working so should I need to add all client principal in keytab file & copy to client machine to perform autologin.
I have tried many API's like JESSO, Waffle, Spring Kerberos, SPNGO but failed to implement auto login.
If you want to use Kerberos/SPNEGO (which would be my recommendation) you do have to set up SPN. And you only need one keytab for AD domain. Are you running your Java program on some app server, like Weblogic, or as a standalone program? Servers do have security framework that you could use, while for standalone program you'd have to do a bunch of stuff manually.
I've found that the easiest way to do this is to use Atlassian's Crowd (https://www.atlassian.com/software/crowd/overview) instead of implementing it yourself. It's a commercial product, but last time I checked, it was dirt cheap, and it just works.
I write a web application I have to do signin in that using the windows username..
I tried to get username using system.get property() but its giving the username of server windows name only.but I want to the username of client system..can any one help me?
If I understood you correctly you want to sign in to the web application using the Windows credentials. If so - the problem is that the server machine knows nothing about the client. It can provide you the user info only after successful login (see Get windows username using JAVA or JSP).
You could point your system to some user store (e.g. LDAP) that will be used by both Windows system and your app. In this situation you will be able to sign in to the app using Windows credentials.
The Browser is an application to generate the view based on an HTML code. It wont give access to the client machine.
You can use request.getRemoteUser() to get the user name, that too is possible only if its allowed in the client machine.
If your client is running on a windows machine you can get the user name using this
var wshshell=new ActiveXObject("wscript.shell");
var username=wshshell.ExpandEnvironmentStrings("%username%");
This is a solution for getting the user name, but i will never recommend this, it surely is a bad practice.
Is the entire Java application running on the server? How would your application even know about a specific client machine? And how would it deal with concurrently logged in users? And how would it deal with a primitive client machine which does not have a notion of a user name?
You can instead run a Java applet which is invoked on the client's machine. You could the send this information to the server to process. However, your users would most likely not like that and not grant the required privileges.
Alternatively, you could try to use JavaScript to read the user name, in case that you are communicating via a webpage. I want to stress the word try in this context since there is not universally functional approach and most users will most likely not allow you to read this property either.
In a nutshell: Users do not normally want to share this information with you and therefore you cannot access it. If you could, you would have found a security hole which would most likely get fixed. Rather, ask your application's users to enter a name to use for whatever reason you would require it. Or, if this is an option, organize for example your Windows credentials in a service that can be accessed by a standardized API.
I am building a java web application that will automatically grant users Administrative Rights to their Windows PC's when a manager approves their request.
In order to accomplish this, I am going to write a script to automatically remote into the users computer and add them to the computer's administrative group. I figured in order to do this though, I will need to have an Administrative Service Account to access all computers.
My question would be, how can I go about securely storing the Administrative Service Account information? The application will need the credentials every time it needs to go and give a user admin-rights, so how can I go about letting the application use the Service Account without human interaction? Obviously I cant just put admin credentials in a plain-text properties file. The credentials shouldn't be open for any developers to see who might go in and change the application later.
Could there be a better way to do this? Someone mentioned to me once maybe having an account in Active Directory to impersonate, but I wasn't able to follow up for more details on that.
There is one method of protecting service account passwords that is occasionally used for services that use databases is based on the concept of inversion of control.
Here the service can call a stored procedure, which has anonymous access, that prompts the database to generate, set, and send the password to the service, whose address it knows, via a separate call.
While the anon call is normally IP limited to prevent DoS attacks, it doesn't matter if some other process calls it, because the stored procedure will only send the password to the service regardless of who calls it.
Currently I take part in developing a system based on Java EE (WebLogic server, to be more precise) and I am wondering how to protect some private data from administrators. For example, some parts of a system stores credentials for legacy systems in a deployment descriptors as plain text and this is bad because a deployer can read application configuration file (ejb-jar.xml, for example) and steal username and password for powerfull account. I want to close this security hole, but don't know how.
Now I am interested in protecting this kind of data:
Login
Password
Private key for symmetric encryption
From here I've discovered that I can use a JCEKS keystore to protect this type of information, but I can not understand how to use it. My application still should contain the kestore password and the key password to access it. So, a depoyer can steal passwords for keystores and keys, find my secure storage and steal credetials. Obviously, I can revoke read privileges from the deployer account, but then he can decompile my appliaction and develop his own similar app (or edit my one), that simply prints secure data to some file or send it by email... And now I am stuck...
Can anybody give me some links that can explain how to protect a system from administrators? Weblogic related links will be preferable. I totally understand that it is not possible to protect from all administrators and there should be some security administrator that will be responsible for keystore management and so forth, but I want to secure all sensitive data from everybody else.
RESULTS
Both jtahlborn's and slim's answers are correct, but slims's answer in more interesting. I think that in my case it will be appropriate to accept only signed applications for installation on the server. This decidion can solve problem with applicatoin modifications done by a administrator. Administrators will have password from keystore and all keys, but they will not have access to keystore file at all. Access to keystore file will have only special security administrators ('rw') and server ('r'). So, everybody will have the key, but nobody (except security administrators) will have access to the box.
There is no solution to this problem unless you enter login credentials at application startup (assuming the admin cannot access the application memory, which may not be a safe assumption). any solution which involves the keys sitting in the same place as the application will result in an administrator (with application filesystem access) being able to access any sensitive data accessible by the application. this is similar to the DRM problem (you can't give someone a locked box and the keys and expect that they can't open the box).
I think the meat of this question is in the definition of "admin".
You've said that you're comfortable with a "security admin" who does have access to key stores.
Traditionally, UNIX types think of "admin" as being the "root" user - someone with access to everything on the machine. Root can do literally anything, right down to peeking and poking at application memory, or reading/writing to raw disk addresses. If the server can get a private key, so can root.
If you want to define an "admin" role with more limited access, then yes, you could set up something where such users existed. They would need to have fewer privileges than the server application itself, since there is at least one thing the app can do (get a private key) that the "admin" cannot.
Such a user probably wouldn't be able to install the app either (since, if they could, they could create and install a version of the app which exposes the private key). Your "admin" couldn't therefore deploy the component that works with the private key. They could, however, potentially deploy a module that runs within that container (as long as the container cannot supply the private key to the module).
However, it's not just the key you want to protect. The real "secret" is the data encrypted using the key. So we still have a problem with the approach above. If the module can read the encrypted data, then so can an "admin" with the same privileges as the module. And that includes anyone who can install the module.
You could investigate ways to sign the module, so that an "admin" could not create their own version.
There comes a point, though, where the measures required to enable untrustworthy admins, become more expensive (in terms of time and effort) than simply using trustworthy admins.
So, you need to make a list of things your so called "admin" can do. Depending on what those things are, it may well be possible to allow a non-root user to do those things. On UNIX, you might use a tool like sudo to allow a non-root user to do things like start/stop the server, read logs, clean logs, etc.
It might be possible to separate the authentication from the rest of the application.
For example, if you communicate with the legacy systems via a TLS-secured socket, you could write a small separate application that accepts unencrypted connections from the application, then makes a secure, authenticated, connection to the legacy system, and pumps data between the application and the legacy system. Essentially, it's an authenticating proxy. Then, the application wouldn't need these keys. You could install and operate the application as a user who didn't have permission to read the files containing the key, but the application could still communicate with the legacy systems.
Of course, now you have the problem of how to authenticate the application to the proxy. You might feel that the machine is secure enough that you don't need to do that at all - as long as the proxy only listens on the loopback interface. If not, if you could use a unix domain socket instead, then you could control access using filesystem permissions: you could run the application as some user in some particular group, then restrict access to the socket to members of that group. Java doesn't have unix domain socket support in the standard library, but you can add it with junixsocket or JUDS.
Given a Java Servlet (running on a Windows server) which creates a new process via ProcessBuilder, what are my options for having that new process run as the user who invoked the original web request to the servlet?
To clarify, what I want is that something like
ProcessBuilder pb = new ProcessBuilder("whoami");
Process p = pb.start();
// p.getOutputStream() should contain the name of the remote user,
// not the user running the app server
And the real goal is to perform some security checks (say, to see if the user if able to open a file, or view such-and-such record in an internal enterprise system).
Clearly the user will need to be authenticated somehow, either by the app server or the java code - Ideally I'd like that to be in some way that works with single sign on (i.e. without the user entering a password), and it's fine if the solution works only from Windows clients who are already logged onto a domain (though even better if that's not a restriction). I'm currently using Jetty as the app server, but switching to something else would certainly be a viable option if necessary.
(If it helps to clarify, I'm basically looking to replace a CGI script which currently uses IIS's impersonation features to run in the context of the user making the request)
Project Waffle will get you (almost) there. It has SSO and impersonation implemented.
Your only option is going to be JNI, or some wrapper around JNI like JNA. You will need to call O/S APIs to change your effective credentials, which will also require the application server to run as administrator - which is itself a significant security consideration.
I don't know specifically about Windows APIs, but most O/S's have the ability for a sufficiently powerful profile (admin/root) to assume the identity of any user profile without needing the password. Otherwise, usually the only way to acquire a user profile token is to present legitimate authentication credentials for that profile.
One thing to be careful of is to ensure that you change the credentials for the thread, not the entire process.