MongoDB: how to create an authenticated db via java driver - java

I'm trying to create an authenticate database in MongoDB 2.6 using java driver v 2.12.
In particular I need to create a user accessing to admin collection.
Any suggestion?
Thanks.

Here my solution:
MongoClient mcAdmin = new MongoClient(
configuration.getServerAddresses(),
Arrays.asList(MongoCredential.createMongoCRCredential(
MONGODB_ADMIN_USERNAME, "admin",
MONGODB_ADMIN_PASSWORD.toCharArray())));
try {
mcAdmin.setWriteConcern(WriteConcern.JOURNALED);
DB db = mcAdmin.getDB(userDbName);
BasicDBObject commandArguments = new BasicDBObject();
commandArguments.put("user", userUsername);
commandArguments.put("pwd", userPassword);
String[] roles = { "readWrite" };
commandArguments.put("roles", roles);
BasicDBObject command = new BasicDBObject("createUser",
commandArguments);
db.command(command);
} finally {
mcAdmin.close();
}

Doing this in Java code is not the best way to do it, and except for very rare use cases (writing an admin application for MongoDB) even one I would strongly advice against.
Security risk
First of all, your application would need extremely high privileges, namely userAdminAnyDatabase or userAdmin on the admin database, which more or less grants the same rights: creating a superuser at will. To put it in other words: this code would be a high security risk.
Granting roles and rights on a database is an administrative task and for good reasons should be decoupled from an application accessible by arbitrary users.
Technical problems
Activating authentication from a client simply is impossible. The mongod instance in question has to be started with authentication enabled. Furthermore, you would have to save to create a user with the mentioned roles before you could have your app administer users. The problem: you would have to store the password for that user somewhere. Unless you encrypt it, you basically store the most powerful password for your MongoDB databases and cluster in cleartext. And if you encrypt it, you have to pass the key for decryption to your application at some point in a secure manner. And all this to break best practices ("Separation of concerns")?

Related

Setting up Firesotre security rules for read acttion for application without login autentication

I have the following rule in Firestore for read if true I recieve email that point anybody can read and my requests can be drained. I need some approach read action to be allowed only from my app.I don't have authentication in the app is accessible without registration.What can I do to restrict the access only from the app.I read can be set SHA1 key but not quite sure how to implement it.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
allow read: if true;
}
}
}
There is no way to do that but there is a way around just add Anonymously authentication with firebase Auth Ui this way users will not have to create an email and they will be authenticated
another way is: try to make some parts which doesn't require security public for anyone to read .
I‘m afraid there’s actually nothing you can do.
Since you are using a backend as a service provider you will have to use some sort of authentication if you want to prevent certain people to execute certain actions.
This could be classic username/password authentication or a more modern means like oauth.
If you only want your application code to be able to access the database, consider setting up Firebase App Check for your project.

Account gets locked every time while trying to access via the V1APIConnector

I am trying to access the VersionOne data using the V1APIConnector. I can verify that I am using the correct data and meta URLs. I also have the correct domain/username and password.
But everytime I execute the below code, I get an Authentication error saying username/password is invalid and my account gets locked.
Once I unlocked my account, I tried again and the account was locked again. I am the V1 Administrator so I have the permissions.
Our VersionOne instance uses Windows Integrated Auththentication. Also my username is in the format -mydomain/myusername
Is there any different way to pass the credentials? Since my account is getting locked, it must mean at least the domain and the username are being passed correctly. Any Ideas?
V1APIConnector dataConnector = new V1APIConnector( _dataUrl, _username, _password);
V1APIConnector metaConnector = new V1APIConnector( _metaUrl );
IMetaModel metaModel = new MetaModel(metaConnector);
IServices services = new Services(metaModel, dataConnector);
System.out.println("Creating query");
IAssetType defectType = metaModel.getAssetType("Defect");
Query query = new Query(defectType);
IAttributeDefinition nameAttribute = defectType.getAttributeDefinition("Name");
query.getSelection().add(nameAttribute);
query.getPaging().setPageSize(3);
query.getPaging().setStart(0);
System.out.println("Retrieve from query");
QueryResult result = services.retrieve(query);
The Java.SDK ignores the username and password parameters of the V1APIConnector constructor when attempting to connect to a Windows Integrated instance, and instead uses the domain credentials that it is running under. If you are logged into your machine as "MyDomain\MyUsername" then that is the credentials that it will use. It does not support supplying the credentials of another account.
Note that there must also exist a VersionOne member account with the username set to "MyDomain\MyUsername" to successfully authenticate.
VersionOne locks accounts only when your license has expired, and if that happens, only the system administrator (Member:20) will remain active. In addition, administrators can deactivate accounts manually.

How to read LDAP password policy in Java

Can i read user password policy from LDAP, like when it expires or more details like password strength (minimal length etc.) ? I need these information so I can use the same policy for users kept in my database. My java application require that users from the database have to be synchronized with domain.
If you want to get the password policy through LDAP queries try this
without PSO policy in your current domain
String searchDomain= "DC=company,DC=ORG";
String ldapQuery = "(&(objectClass=domainDNS))";
String ldapAttribute = "maxPwdAge";
If you use a PSO policy try this code
String domainLookupString = "CN=UsersPSO,CN=Password Settings Container,CN=System,DC=company,DC=ORG";
String ldapFilterString = "(&(objectClass=msDS-PasswordSettings))";
String ldapAttribute = "msDS-MaximumPasswordAge"
Usually, there are at least three different things that are of concern in these circumstances.
Account status, which includes such information as is the account locked, expired or disabled.
The account "status" is typically reflected on the MMC Account Tab.
We put some information on our wiki about the LDAP values at:
http://ldapwiki.willeke.com/wiki/Active%20Directory%20Account%20Lockout
and
http://ldapwiki.willeke.com/wiki/MMC%20Account%20Tab
Password status, is the password expired.
Unfortunately, the attributes that reflect the status of these conditions are not reflected in AD in real time. Some are only updated when a user attempts to authenticate. (either successfully or un-successfully).
-jim
Yes you can, with JNDI. You have to read the value of the pwdPolicySubentry operational attribute from the user's Context. This gives you the DN of the pwdPolicy object, which you then lookup as a Context with attributes, and get all the attributes starting with 'pwd'. However if the user has the default password policy you will have to look at your LDAP server configuration to find its DN. In OpenLDAP this is in slapd.conf in the ppolicy_default line in the 'overlay ppolicy' directives block.
It depends the underlying LDAP server.
For instance, if you are using Microsoft Active Directory, a user entry will have an attribute called accountExpires which is the date the account expires.
Active Directory also have a user attribute called userAccountControl which is a bit-mask specifying various account related states. For instance, if bit 24 is set, that means that the password has expired (userAccountControl & 0x800000 != 0). Bit 2 is "account disabled" etc. Read more at http://support.microsoft.com/kb/305144.
For other LDAP servers (OpenLDAP, ApacheDS, etc, etc) you'll have to look into the documentation.

App Engine Java - Currently Using Federated Login/Openid - How Should I Persist a Successfully Authenticated Facebook User?

I have my Google App Engine Java application humming along nicely using openid/federated login.
I save a UserProfile object that I persist once we have a logged in user that saves a reference to the UserService.getCurrentUser() object (and its userid) like so:
UserService userService = UserServiceFactory.getUserService();
user = userService.getCurrentUser();
userId = user.getUserId();
profile = UserProfileBin.getInstance().getByUserId(user.getUserId());
if (profile == null) {
profile = new UserProfile();
profile.setUser(user);
profile.setUserId(user.getUserId());
profile.setCreatedDate(new Date());
pm.makePersistent(profile);
id = profile.getId().getId();
}
...
Well, that is all working fantastically. I'm using the openId selector and am logging into the app using a bunch of different openid providers. There are no issues.
Now, I want to let people use their facebook logins, and I have that part going as well. I'm using the server side authentication flow. I'm able to complete the authorization and retrieve the access token, and I am using restFB. I can connect to the graph api and get whatever I need.
So my question is this: I don't know what the best way is to go about taking this information and letting my app know that somebody is logged in.
I assume Userservice.getCurrentUser() is a no go.
I see OauthService.getCurrentUser(). That would be awesome if that "knew" that I had a Facebook user logged in. Then my user checks would just be along the lines of:
User user = UserService.getCurrentUser()
if(user == null)
{
user = OAuthService.getCurrentUser();
}
and merrily on my way I would go.
However, I don't see a way to register my Facebook user with OAuthService or anything.
I'm sure this has been done before.
How should I go about it? Is there a cute way to do this, or am I stuck turning on sessions and making a custom user object for my Facebook user and sticking it in the session and running a filter?
You'll need to enable sessions and store the relevant info about the user's login in the session. You may be able to configure things so that session data isn't loaded for users who are logged in using OpenID. I'm not sure, though, because I'm not overly familiar with Java.

Implementing two-factor authentication into a Java web app

I have an existing Java web application running through IBM WebSphere (I'm unsure of the version, but could find out if it helps) that I am looking to implement two factor authentication with.
The system has a decent user base, and I wanted to distribute hardware tokens to the admin users of the system to ensure strong authentication.
Minimal impact to the end user is desirable, but I'd like to avoid having the admins need to go through a VPN connection.
Does anyone know of any products that provide Java APIs that could be directly integrated into the existing application or other products that will provide a minimal impact? I've already spoken with RSA SecurID, but their system wouldn't integrate directly and would require an infrastructure change. Any other ideas/experience is greatly appreciated.
For posterity, I've just posted my simple Java two factor authentication utility class to Github. With it, you can do something like the following:
TwoFactorAuthUtil twoFactorAuthUtil = new TwoFactorAuthUtil();
// To generate a secret use:
// String base32Secret = generateBase32Secret();
String base32Secret = "NY4A5CPJZ46LXZCP";
// now we can store this in the database associated with the account
// this is the name of the key which can be displayed by the authenticator program
String keyId = "user#j256.com";
System.out.println("Image url = " + twoFactorAuthUtil.qrImageUrl(keyId, base32Secret));
// we can display this image to the user to let them load it into their auth program
// we can use the code here and compare it against user input
String code = twoFactorAuthUtil.generateCurrentNumber(base32Secret);
// this little loop is here to show how the number changes over time
while (true) {
long diff = TwoFactorAuthUtil.TIME_STEP_SECONDS
- ((System.currentTimeMillis() / 1000) % TwoFactorAuthUtil.TIME_STEP_SECONDS);
code = twoFactorAuthUtil.generateCurrentNumber(base32Secret);
System.out.println("Secret code = " + code + ", change in " + diff + " seconds");
Thread.sleep(1000);
}
If you want two-factor authentication via a TLS client-certificate, there are a few hardware cryptographic tokens out there. Java can load a PKCS#11 store out of the box, although some configuration may be required. How much of it is admin configuration vs. application configuration depends on the application (and sometimes on how 'locked' the terminal is w.r.t to inserting a USB token or having a card reader).
There may be alternative solutions, such as One-Time Password tokens (which don't rely on certificates, but on unique passwords instead). This seems less heavy for the users. I must admit I've never tried it, but this project might be interesting: http://directory.apache.org/triplesec/ (There are also hardware OTP keyrings, usually by the same vendors who do RSA cards/USB tokens).
We have API packages for Java (and php, ruby, python, and C#): http://www.wikidsystems.com/downloads/network-clients for the WiKID Strong Authentication system. These packages are LGPL, so you can also use them in commercial products. They work with both our open-source community version and the commercial Enterprise version.
HTH,
Nick
If you are able to use Spring Security we have a plugin which offers two factor authentication (physical and soft tokens) - www.cloudseal.com

Categories

Resources