Using windows domain authentication for authentication - java

The title may seem a little weird but what I find around the internet is methods to sign on to stuff automatically with windows domain authentication (Single Sign On), but that is not what I want.
In my use case I want to explicitly ask the person to enter their windows domain user/password combination to make sure that the person performing the transaction is the one that is authorized to do so, i.e. not someone who secretly makes use of the authorized person's computer while he/she is away and left their computer unlocked.
Note
I am working on Java
I only want to authenticate a single transaction, no login session (if possible).
Only certain people should be authorized. (I believe this is done through roles in active directory?)

What I have used in the past is to authenticate against an LDAP server. Active directory works as an LDAP server so you should be able to authenticate against it. This can be used to verify the username/password combination.
I found this article showing how it works with java.

Related

How can I hide my database information in Java?

I'm trying to figure out database security in Java. Like video games, desktop app and others that uses database in its code and how they can store their password in it.
Here's an example:
There's an application that uses MySQL database for storing users data and their information.
A user is registered and logged into our app. He has 0 coin in start. He bought 100 coin from shop and his coin data changed to 100. During the steps that I mention, he always use database for insert and update his data.
In a nutshell, how can I hide my database information (username and maybe IP?) in my Java code?
In addition, I've searched a while and found that you can send web request for information, but if anyone finds the code of request, they also can make their program and use same request as my app. So, I cannot figure this out.
Usually, the database is in a server that you controls, and you provide an API to make requests.
In these requests there's no information about database username or password, that should be on your server.
Then, you need to protect that connection. Normally, yo do that with authentication and authorization. You need to provide username and passwords to your users, and that is present in any request they do to your server. Also, you need to make controls in your server to control what can do each user (control that a user cannot perform any query they want).
A common way to do this is using federated authentication and authorization, with protocols like OAuth2.0 or OpenID.
Also, you need to make sure that you use HTTPS, or attackers could capture the traffic and extract all the request information.
Short answer: you never talk from the Front End (UI, mobile application, whatever) to the Database.
Usually Frontend talks to some backend server - an entry point to the backend word, a gateway (there is indeed such a term). From that point, the request can be routed to another server, or be processed in the same server (depending on the application, its complexity, architecture, etc) and only after that the information should be stored in the database (or queried from the database and returned back to the end user).
Only the gateway is exposed to the "outer word", all the backend services and of course the database should be protected from the accidental/malicious access at different levels:
at the level of network so that it will be physically impossible to connect to it if you're not making a connection from one of the backed servers
at the level of application security - so that it will be impossible to connect to the database without appropriate credentials (username, password, etc). Note this are not the same Username/password that the end user must know in order to login to the application, these are the data about the user, it has nothing to do with the user / password required to connect to the database.
The answer to your specific question is to use Java's "secret storage" features. This question may be a starting point.
The wider point is - please do not make a MySQL database directly accessible from the internet if that's what you're thinking. The security of such a solution would require specialist skills and your question suggests you don't have those skills...
If your application runs outside a local area network (and even if it runs inside the network), you probably want to put a central service layer in place - and API - to handle requests from your client applications. In this case, you still need authentication - you don't want to allow unauthenticated users to add, remove or spend your coins. Most API frameworks have out-of-the-box solutions for this.

Good practices and pitfalls when bypassing a SSO system through another server?

I'm in charge of maintaining a web application (Lives on a Tomcat server) which has two different access points, through two Apache HTTPD servers which are outside of my reach.
The two access points are meant to log in user either through a third-party SSO system or a good ol' authentication page which prompts for login and password.
The trick is, this SSO puts a limit on the size of files which can be uploaded or downloaded. As SSO users will need to retrieve and send things heavier than that, I need a workaround for this, most likely simply offering a link pointing to the correct resource location through the other server.
What concerns me here is security, in case someone enters a cleverly guessed address to get a document he's not supposed to. The person in charge doesn't want to hear about a SessionManager to make sure the user has the rights to retrieve the documents, but suggested that I could simply use their JSESSSION_ID to confirm their identity...
I am not sure about how to implement this, and have a serious gut feeling that this will backfire in a quite horrible fashion.
Can anyone who had to deal with a similar problem points some of the pitfalls and possibly share a few useful tips on how to securely bypass this SSO ?
One possible way to implement this is to protect the resources on the non-restricted site with a one-time password with a very short life time.
Example:
User clicks on a link to open a document on the SSO protected site. The link should not provide the document directly.
The Tomcat server generates a one time password and redirects (using http code 303) the user to the un-restricted site with this password as an http parameter.
3. When the browser connects to the un-restricted site, check that the password is correct and provide the document. Delete the password so that it cannot be used again.
The password should only be valid for say 30 seconds. You may also record the user's ip-address and validate that.
You should not use the jsession id for this. It is not a good practise to expose the jsession id in a parameter on the address bar or in an html page.
However, you say that the other access point is protected by username and password. If so, will not the user have to log in here anyway? And if so, does not that login protect the resources?
If you provide a link pointing to the correct resource, we need to consider the security.
https://www.owasp.org/index.php/Top_10_2010-A2
The most important thing is XSS and CSRF and solutions are provided in the above website.
Session Hijacking can be another security threat if we provide a direct link which can directly access the resources.

Add login system to simple JSP site

RESOLVED. This question can be deleted by moderators
I have a very simple site written using Java EE (JSPs, Java, Tomcat server). I want to implement a simple login system. I thought I got the registration and login working; however, there is a huge problem with the way I'm doing it.
Let's say Alice logs in. She is able to view her profile with her information, everything looks normal so far for Alice.
Then Eve comes around and wants to log on. She does and is taken to her profile, everything looks normal for Eve.
Then Alice reloads her profile to find that the site now has her logged in as Eve!
So to reiterate: after one person is logged in, anyone is able to go to the site and be logged on to that account. And the most recent person to log on is the active account.
How do you keep track of session information like this so that multiple different accounts can be logged on using the site at the same time?
Thanks!
EDIT:
This ended up being a very simple fix.. I just need to use setAttribute("EMAIL", userId); rather than the stupid way I did it which was just using a global String variable
Rather than try to roll your own security, use an existing framework, like Spring Security. Out of the box, it gives you basic login capabilities and handles securing pages using a role-based authentication scheme.
Reading your problem, I think that you store the last logged user's credentials in an instance variable of one of your servlets. This causes the last person to log in to overwrite everyone's credentials...
If you want a simple authentication, you can use Java EE's provided system :
http://docs.oracle.com/javaee/5/tutorial/doc/bncbx.html
Once a user logs in, put his own credentials in his Http session (request.getSession().put(username, )). Then, everyone will have a distinct profile.

multiple active directory server authentication using java

i have three active directory servers different address,port and domain name and all
In my app when user log-in the system i have to authenticate. The user provide his username and password only not the domain name or ip address.
How can i authenticate him, whether i have to loop through the all the ldap server and when i get the Context i have to break it .. or is any other possible solution is there for authenticate a user in multiple servers
please suggest. thanks in advance
If the user gives his FDN or UPN (User Principal Name) instead of just an user name it will be helpful. But still there is no guarantee that upn will match your realm name. If he gives FDN then atleast you can cache defaultNamingContext from all the three server and try to match it with the fdn provided by the user and authenticate him against the matching server.
But I guess he is providing the samAccountName in your case. In this case we dont have any clue to identify the server. You have to go through one by one and probably cache it which server he is authenticated against for next time performance improvment. Its also possible that the same username exist in multiple AD. You have to handle this case based on your AD environment.
as a additional note, if its web application try using spring's ldapTemplate. This might ease your task.

How to translate a domain name to LDAP DC when working in a Active Directory forest in Java?

I am struggling with a problem where I wasn't able to find a lean and generic solution. This is my situation:
I am in a huge AD forest with > 20 sub domains replicating over several hundreds servers. Say the main domain and Kerberos realm is COMPANY.COM and I am working in D1.COMPANY.COM.
I do connect from Java to the global catalog and are able to access the entire forrest to support all company users.
My connection URL is like this: ldap://mycompany.com:3268/DC=company,DC=com
The entire stuff is running in a webapp using SPNEGO to authenticate the users which works very well. I.e., after sucessful login I do receive the users UPN/Kerberos principal. Due to some reasons all UPN fields in the forest where altered to match user's email address rather to leave the UPN value intact. This means that I an not able to search for the search by the krb princ but I have to strip out the username and search by sAMAccountName.
I presumed the sAMAccountName is unique in the entire forest until a user failed to login yesterday. After some LDAP query magic I figured out that two users have the same sAMAccountName in two different domains. My search fails.
So the issue is, how do I determine the base DN/DC of a realm/sub domain based in the Kerberos realm?
I figured out several approaches with a stripped realm string:
constuct an LDAP URL and connect to and read defaultNamingContext
reformat domain name to DC=d1,DC...
Currently, I am using approach 2 which seems to be the easiest way. Altough some C# post here on stack overflow said that this might fail due to disjoint spaces.
Is anyone aware of a safe solution? The best would be actually to translate Kerberos principals to user principal names.
After login you get the UPN which is a email. The username part of it can be used because its not unique. The domain part can not be used because it need to be same as naming context. You may have the dc=mydomain,dc=com but the domain for the email can be like myemaildomain.com. And I can add this as additional UPN as well, i guess this is what happened in your case.
Do not take the second approach. Take the first one.
Do a dns srv lookup _ldap._tcp.domain.com
Read about DnsQueryConfig to get the configured domain name
Get the server name.
do a rootDse search requesting namingContext.
and construct the ldapurls
Further..,
it looks like the emailid in your domain is unique across the forest (?)
If so, may be you can mark the email id as PAS attribute so that every GC has the copy of it and do a ldap search on the GC port for emailid. But this is a very bad option as this requires schema changes that too with more than 20 subdomains.
Kaylan, the oVirt project (www.ovirt.org) contains Spring-Ldap code that shows you how to authenticate with Kerberos against Active-Directory, RHDS, ipa, and Tivoli-DS. We still need to continue and implement forest functionality (Just asked a question about CLdap implementation in Java for that). In order to get defaultNamingContext you will have to issue a RootDSE query (we have some code for that as well in oVirt) to the desired domain.
You can download the sources by performing git clone, or you can browse them using http://gerrit.ovirt.org
Please look at the code under engine\backend\manager\modules\bll\src\main\java\org\ovirt\engine\core\bll\adbroker
You will see there all you need for your this.

Categories

Resources