JLDAP for Authentication - java

I'm working on an application that requires the use of LDAP for authentication. Every student at my University has a MyID. There is a wiki on one of the University's pages that states:
To form the full DN (distinguished name) of a MyID, use this format:
cn=MyID,ou=users,o=uga (where MyID is replaced by the user's MyID).
In LDAP, a NULL password or username is considered an anonymous bind
attempt (bind is the LDAP word for authentication) and will always
succeed. Your application should either filter out NULL password
strings or validate the successful bind attempt. To validate a bind
attempt, have your application attempt to read the attribute
ugaAuthCheck. The attribute should have the value of 'y' (the letter y
without the quotes).
I am using JLDAP to handle connecting to the LDAP server over SSL. I am able to search the directory once connected, but I'm at a loss as to:
To validate a bind attempt, have your application attempt to read the
attribute ugaAuthCheck.
I bind to the server with this JLDAP method:
lc.bind( ldapVersion, loginDN, password.getBytes("UTF8") );
How does one read an attribute off of a bind in JLDAP? I've been digging through the JLDAP source but I'm not really seeing what an attribute is....so perhaps its actually called something different?

There are JLDAP Samples provided by Novell.
You might want to look at the "CompareAttrs.java" or "Search.java" code for some ideas.
-jim

Related

Failed to update user in Active Directory (using Boomi mapping)

I can create user using Boomi without any SSL(means using port389) and password(for new user to login) but I want to change user's phone number, and I got this error:
javax.naming.OperationNotSupportedException: [LDAP: error code 53 - 00000057: LdapErr: DSID-0C042612, comment: Error in attribute conversion operation, data 0, v4563?]; remaining name ''???at java.naming/com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3332)???at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3205)???at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2996)???at java.naming/com.sun.jndi.ldap.LdapCtx.c_modifyAttributes(LdapCtx.java:1504)???at java.naming/com.sun.jndi.toolkit.ctx.ComponentDirContext.p_modifyAttributes(ComponentDirContext.java:277)???at java.naming/com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(PartialCompositeDirContext.java:192)???at java.naming/com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(PartialCompositeDirContext.java:181)???at java.naming/javax.naming.directory.InitialDirContext.modifyAttributes(InitialDirContext.java:167)???at com.boomi.connector.LDAP.LDAPConnection.updateObject(LDAPConnection.java:190)???at com.boomi.connector.LDAP.LDAPUpdateOperation.executeUpdate(LDAPUpdateOperation.java:227)???at com.boomi.connector.util.BaseUpdateOperation.execute(BaseUpdateOperation.java:30)???at com.boomi.connector.generic.GenericConnectorAction.invoke(GenericConnectorAction.java:189)???at com.boomi.connector.generic.GenericConnectorAction.invoke(GenericConnectorAction.java:172)???at com.boomi.connector.base.BaseConnectorAction.invokeBase(BaseConnectorAction.java:368)???at com.boomi.connector.base.BaseConnectorAction.invokeWithReadStore(BaseConnectorAction.java:304)???at com.boomi.connector.base.BaseConnectorAction.invoke(BaseConnectorAction.java:276)???at jdk.internal.reflect.GeneratedMethodAccessor29.invoke(Unknown Source)???
and I googled this error means:
Indicates that the LDAP server cannot process the request because of server-defined restrictions. This error is returned for the following reasons:
1. The add entry request violates the server's structure rules
2. The modify attribute request specifies attributes that users cannot modify -> I just want to change phone number.
3. Password restrictions prevent the action
4. Connection restrictions prevent the action. -> I think I can create user, so the connection is fine!
If LDAP error Code 53 means I need to do everything with "SSL", why I can create a user? How can I sort this problem out?
It's possible the user actually hasn't been properly provisioned. Maybe it's been created, but the account is not enabled because the password is invalid. Run an LDAP client and try and logon as the new user with the credentials that you supplied. Does it work?
Two suggestions:
Please use LDAPS if you're creating users/setting passwords, or basically anything in AD LDAP. There's no excuse not to these days, and Microsoft is in the process of deprecating plain LDAP from non-Windows clients, so you might as well do it now. All you need is to install/trust the issuing CA certificate chain (root and intermediate certs) for whatever CA is signing the DC's LDAPS certificate. You do not need to install any client LDAP cert.
Check the password policy of the target domain and ensure the passwords you are trying to set meet the requirements in terms of complexity, length and so on.

Modify audit trail in Alfresco using a custom webscript

I am writing a custom Java webscript that accepts document noderef and an external username (string value) as parameters. I have auditing enabled and the audit log shows access to the document when I call the webscript. Now I wanted to know if it is possible to modify the audit trail so that when it shows the log for that particular document it also shows the name of the external user.
webscript url: http://localhost:8080/alfresco/service/node/{noderef}/user/{user}
On calling this I get the following output in log:
Extracted audit data:
Application: AuditApplication[ name=alfresco-access, id=1, disabledPathsId=2]
Values:
/alfresco-access/transaction/sub-actions=readContent
/alfresco-access/transaction/action=READ
/alfresco-access/transaction/node=workspace://SpacesStore/c21db432-4ad6-4af2-8bcf-78bc89724afe
/alfresco-access/transaction/type=cm:content
/alfresco-access/transaction/path=/app:company_home/app:shared/cm:audit-services-context.xml
/alfresco-access/transaction/user=admin
New Data:
/alfresco-access/transaction/sub-actions=readContent
/alfresco-access/transaction/action=READ
/alfresco-access/transaction/type=cm:content
/alfresco-access/transaction/user=admin
/alfresco-access/transaction/path=/app:company_home/app:shared/cm:audit-services-context.xml
I want to store the {user} also in the audit trail.
You can try to use AuthenticationUtil.setFullyAuthenticatedUser. I think this should help you. But I didn't test this.
You probably do not want to do that, at least not in the way you describe, not without making extra security precautions.
This goes IMHO opinion against security standards, if admin needs to read a document,the operation needs to be logged with his username, if a normal user needs to access a document, he needs to be properly authenticated for that operation.
Judging from the little context I have I would say this is actually an integration with some other app that does not share SSO with Alfresco. So I would recommend a solution of the following :
Use proper SSO between Alfresco and your application, have the concerned user ping the right endpoint in Alfresco and let SSO authenticate the request properly for you.
Use a shared secret (something like a shared passphrase to encode encode the authority name in the request + proper authentication subsystem or request filter to handle that) or a key pair (something like securecomms between solr and alfresco) to be able to securely pass on authority information to the request
Use a system account (preferably not admin, but one that is dedicated to this usecase/application integration) to generate a valid alf_ticket for the user in question, and have your app attach that ticket to the request. (Of course, your "impersonate" webscript would need to check for the right system/integration username, before running the snippet to get the alf_ticket from a runAsSystem block). In this case, I would also recommend not using the admin account for this but rather use a user with no permissions at all except for this usecase.
If you are going to opt for the quick implementation that you have, I would recommend at least the following :
You need to make sure that not any user can ping that webscript and that only admin/system user can actually access that webscript.
You probably should log the whole impersonation operation in the audit trail (either using the same audit entry or a separate one), so that it would be clear that this is actually an operation that was made on behalf of the user and not directly by the user himself
If you use the webscript in question for anything other than reading the content of the node (Can be the case also if you have a onReadContent behaviour that has some nasty AuthenticationUtil.setFullyAuthenticatedUser as well), and you require that operation to be logged as system/originally authenticated user, You will probably have a hard time doing that... and you should switch to a more robust approach!

How to retrieve UPN(User principal Name) of current logged in user using Java

I want to retrieve UserPrincipalName of current logged in user using java.I can connect to AD and retrieve that, but i want to avoid all those configuration and other stuff, is there an easier way to get UPN using java?
UPN stored in AD is usually in userName#domainName format. If my user is john and domain is vmware, it should return john#vmware.
Please advise.
Java and JavaScript are separate languages. For a java servlet you can get the UserPrinciple name property with
GetPageContext().getRequest().getUserPrincipal().getName()
For javascript you'd need to have the server provide this via rendering it as a value, or have some framework or AJAX that allows the user principle be added to the response data or callable via the page script.

Android, AccountManager and OAuth

I'm sure this is basic and I'm missing something. I've read through other answers on SO, I've googled, I've read resources and I just can't wrap my head around what I need to do.
I'm trying to figure out how to write an app that connects to Twitch's API, specifically how to authenticate with Twitch's api. Their documentation is here: https://github.com/justintv/Twitch-API/blob/master/authentication.md
I've created an app and stored my keys.
Now comes the part where I want my user to click a button which launches the authentication on their website. From what I can tell I do this by using an AccountManager. Except... I can't figure out what I'm supposed to do.
Here's the excerpt I've found online:
AccountManager am = AccountManager.get(this);
Bundle options = new Bundle();
am.getAuthToken(
myAccount_, // Account retrieved using getAccountsByType()
"Manage your tasks", // Auth scope
options, // Authenticator-specific options
this, // Your activity
new OnTokenAcquired(), // Callback called when a token is successfully acquired
new Handler(new OnError())); // Callback called if an error occurs
According to twitch's documentation I want to send the user to:
https://api.twitch.tv/kraken/oauth2/authorize
?response_type=code
&client_id=[your client ID]
&redirect_uri=[your registered redirect URI]
&scope=[space separated list of scopes]
&state=[your provided unique token]
And I simply have no idea how these two things need to be combined.
Firstly, I recommend to read the OAuth2 RFC. This should cover everything you need to know.
The AccountManager code snippet won't help you much unless there already is an app that provides authentication for Twitch. If that's not the case you either need to use an existing OAuth2 library or implement your own.
You could write your own AccountAuthenticator but that's a different challenge (and you still need some kind of OAuth2 client).
Doing it yourself is not that hard, see below.
Steps to implement it yourself
Twitch recommends to use the "Implicit Grant Flow" for mobile apps. That's what I'm going to describe below.
1. Get a client ID
Register your app as outlined in Developer Setup to get a client ID
As redirect URI you can use something like https://localhost:12398/, the actual port doesn't really matter.
2. Build the authentication URL
In your client app you need to construct the authentication URL like so:
https://api.twitch.tv/kraken/oauth2/authorize?
response_type=token&
client_id=[your client ID]&
redirect_uri=[your registered redirect URI]&
scope=[space separated list of scopes]
Apparently [your client ID] should be replaced by the client ID you've received from Twitch, same goes for [your registered redirect URI] (that's the URL above, i.e. https://localhost:12398/). [space separated list of scopes] is the list of scopes (i.e. features your want to access), see Scopes. Make sure you URL-encode the parameter values properly.
Assuming your client ID is 123456 and the scopes you need are user_read and channel_read your URL would look like this:
https://api.twitch.tv/kraken/oauth2/authorize?
response_type=token&
client_id=123456&
redirect_uri=https%3A%2F%2Flocalhost%3A12398%2F&
scope=user_read%20channel_read
Note that you should also pass a state parameter, just use a randomly generated value. You can also append the (non-standard) force_verify parameter to make sure the user actually needs to log in each time (instead of continuing a previous session), but I think you can achieve the same by clearing the cookie store (given that you open the URL in a webview in the context of your app) before you open the login page.
With a random state the URL would look like this:
https://api.twitch.tv/kraken/oauth2/authorize?
response_type=token&
client_id=123456&
redirect_uri=https%3A%2F%2Flocalhost%3A12398%2F&
scope=user_read%20channel_read&
state=82hdknaizuVBfd9847guHUIhndzhuehnb
Again, make sure the state value is properly URL encoded.
3. Open the authentication URL
Ideally you just open the URL in a WebView inside of your app. In that case you need to intercept all request to load a new URL using WebViewClient.shouldOverrideUrlLoading
Once the client is redirected to your redirect URL you can close the webview and continue with step 4.
Theoretically it's possible to utilize the default browser to do the authentication, but I would have security concerns since an external app could learn about your client ID and the access token.
4. Extract the access token
The actual URL you get redirected to in step #3 will have the form:
https://[your registered redirect URI]/#access_token=[an access token]&scope=[authorized scopes]
or to pick up the example
https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read
Where xxx is the actual access token.
If you passed a state it will be present like so:
https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read&state=82hdknaizuVBfd9847guHUIhndzhuehnb
All you have to do now is to parse the (URL encoded) access token, scope and state. Compare the scopes and state to the ones that you actually sent. If they match you can start using the access_token to authenticate.
Note According to the OAuth2 RFC, the response URL MUST also contain a token_type and it SHOULD contain an expires_in duration in seconds.
Once you received the access token you can use it to authenticate as described here.
Access tokens issued by the Implicit Grant Flow usually expire after a certain time and the user needs to authenticate again. The Twitch documentation doesn't mention any expiration time, so it's possible that the token is valid forever. So make sure your app doesn't store it or store it in a secure way (like using Android's key store provider to generate and store a key to encrypt the access token).
If the implicitly issued access token expires you could consider using the "Authorization Code Flow". That's quite similar but it contains an additional step to receive the access token and a "refresh token" that can be used to renew the access token. I leave it up to you to figure out how that works.

Disable REST security and authentication- Websphere Commerce

I want to access Subscription's REST,
For instance ;
/store/{storeId}/subscription?q=byBuyerIdAndSubscriptionType
Ref:https://www-01.ibm.com/support/knowledgecenter/SSZLC2_7.0.0/com.ibm.commerce.starterstores.doc/code/rsm_subscription_fep8.htm?lang=en
but if I explicitly pass member_id of the buyer of subscription to the REST call on some other user's login, it gives me authentication error and doesn't return anything.
User 2581 does not have the authority to perform action "Display" on resource "com.ibm.commerce.subscription.facade.server.authorization.SubscriptionTypeProtectableProxy" for command "Display".
What should I do to byPass this authentication and get desired data?
You could try giving this line in your wc-rest-security.xml file.
<partialAuthentication resource="store/{storeId}/" method="GET" enabled="false"/>
You could also be specific and mention
store/{storeId}/subscription
instead of
store/{storeId}/
I haven't verified the above line, but I am pretty sure the solution to your issue lies in configuring the wc-rest-security.xml file. Link to the IBM Documentation on this : https://www-01.ibm.com/support/knowledgecenter/SSZLC2_8.0.0/com.ibm.commerce.webservices.doc/tasks/twvrestpartialauth.htm
You shouldn't. For obvious reasons.
You should not allow access to other users' subscription data. If what you're trying to accomplish is to allow specific users access to other users' data (e.g. a CSR), then you need to solve this through access control policies and appropriate user roles.

Categories

Resources