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

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.

Related

Authenticate with Cognito Federated Identities

I am having a hard time trying to figure out how to use Amazon Cognito in my web app (Java based). I want to have some kind of authentication hub (Amazon Cognito) to authenticate user with multiple Auth Providers - that's why I want to use Amazon Cognito! :)
Firstly, I set up User Pool (I have my UserPoolId: eu-central-1_xxxxxxxxxx) and created there one user. Next I created Identity Pool with IdentityPoolId (eu-central-1:yyyyyyyyyy). Then I authenticate with AWS JavaScript SDK to UserPool to get idToken and it working quite fine! I receive idToken from Cognito UserPool. Then I am sending this idToken to my backend app (Java based) and there I want to validate this idToken with IdentityPool. I added new Authentication Provider - Cognito with UserPoolId and newly created id of an App that I added in UserPool. I tried to follow with this tutorial:
https://aws.amazon.com/blogs/mobile/use-amazon-cognito-in-your-website-for-simple-aws-authentication/
But everytime I make
GetID
request I recevied Exception with
com.amazonaws.services.cognitoidentity.model.NotAuthorizedException: Token is not from a supported provider of this identity pool.
My Java code is below:
final AmazonCognitoIdentityClient identityClient = new AmazonCognitoIdentityClient(
new BasicAWSCredentials("accessKey", "secretKey"));
identityClient.setRegion(Region.getRegion(Regions.EU_CENTRAL_1));
GetIdRequest idRequest = new GetIdRequest();
idRequest.setAccountId("accountId");
idRequest.setIdentityPoolId(identityPoolId);
final String providerName = "cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxxxxxx";
Map providerTokens = new HashMap();
providerTokens.put(providerName, idToken);
idRequest.setLogins(providerTokens);
GetIdResult idResp = identityClient.getId(idRequest);
Does anyone could help me with this task? Maybe I am doing something wrong?
Thanks,
Kamil :)
There are three pieces of data that need to match in this scenario:
Provider as configured in AWS.
Provider as put into the Logins map.
iss value (issuer) in the id token.
When I have seen this error, it has been because the value in the Logins map does not match the provider as configured in AWS.
For example, an unexpected port number or trailing slash can cause these not to match.
Beyond this, there are a couple of settings in AWS that need to line up.
Provider as configured in AWS
With a Cognito User Pool, Amazon configures this name for you, so it's non-configurable on the backend. The format of the providerName in your Java code looks good, but first I'd triple check the xxxxxxx part for a typo.
App Client settings
Then, make sure your App Client has Cognito enabled in your User Pool settings:
Federated Identities settings
Next, in your federated identities settings, verify that the user pool id and client id appear in the Cognito tab under "Authentication providers", and that they match your user pool and App Client.
JWT issuer
Finally, I would expect the error to be "Invalid login token. Issuer doesn't match providerName" if there was a problem with the iss value in the JWT. However, decoding the id token you get back and inspecting the contents (as suggested in another answer) is also good advice.
If all these pieces appear to be in place, and the error persists, please leave a comment. Happy Hacking!
When you created your user pool double check you have all the expected federated providers supported. If you use developer authenticated make sure you add that 'login....' domain as well.
Grab your/a token and look at it in jwt.io for clues as well.

Error in response while using SAML oneLogin code to connect to ADFS as iDP

We are able to login to the ADFS iDP through the saml OneLogin java application.
we have followed below steps to Edit the Claim rules of Relying Party(ADFS) to:
enable return of email address in response.
Right-click on the relying party trust and select Edit Claim Rules….
On the Issuance Transform Rules tab select Add Rules….
Select Send LDAP Attribute as Claims as the claim rule template to use.
Give the claim a name such as NameID.
Set the Attribute Store to Active Directory, the LDAP Attribute to E-Mail-Addresses, and the Outgoing Claim Type to E-mail Address.
Select Finish.
Select Add Rule….
Select Transform an Incoming Claim as the claim rule template to use.
Give it a name such as Email to NameID. Incoming claim type should be E-mail Address and the Outgoing name ID format is Email.
Check Pass through all claim values and click Finish.
But it gives below exception:
Microsoft.IdentityServer.Protocols.Saml.InvalidNameIdPolicyException: MSIS7070:
The SAML request contained a NameIDPolicy that was not satisfied by the issued token.
Requested NameIDPolicy: AllowCreate: True Format: urn:oasis:names:tc:SAML:1.1:nameid-format:
emailAddress
SPNameQualifier: . Actual NameID properties: null.
Please advice how to resolve this error. Thanks for your help.
I have resolved this exception. It required to add email address in the properties of Active Directory Users and Computers on ADFS server. Also, the NameID format property should be set as "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
Thanks everyone for your support. Hopefully, this might help someone.

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.

Java JNDI - limitation when changing user's password in Microsoft LDAP - authentication exception

This is my first post here. I have tried to search in internet for my question but found no answers. I hope your expertise will help me.
I noticed something annoying when working with Microsoft LDAP in particular. In LDAP when the user must reset their password at next logon there is a flag "User must reset password at next logon", lets call it flag X. When X is set for a user and if we try to change this user's pass we cannot. I want to do this from the name of the user not as another administrative user - so it becomes that user must change pass but if you try to change it you cannot..
Here is what I am doing:
Hashtable env = new Hashtable();
env.put(Context.SECURITY_AUTHENTICATION, <auth_mech>);
env.put(Context.SECURITY_PRINCIPAL, <principal>);
env.put(Context.SECURITY_CREDENTIALS, <pass>);
DirContext ctx = new InitialDirContext(env);
When trying to create the new Initial Context:
Authentication exception [LDAP: error code 49 - 80090308: LdapErr: DSID-0Cxxxxxx, comment: AcceptSecurityContext error, data 773, vece]
data 773 means - user must change their pass at next logon. So when:
- user must change their pass at next logon
- user pass is expired
- user account is disabled
- user account is expired
and so on we cannot change the user' password... This seems to me as a big limitation.
Also I want to ask if someone knows a specification that Micrisoft are following regarding this error codes. I know that error code 49 is general error code and is according to specification, but this data 773, data 532 are they general for all LDAP as I think they are specific to the vendor which is again very annoying.
P.S. I found similar issue here:
Change AD user expired password in Java
but it was resolved when using AD Super user that can change everyone's password, but I don't want that, I need the user to be able to change their own passwords as this is reflects in the LDAP Password History.
Thanks
The user can't change his own password if he can't login. If his password is expired you have to reset it as an administrator and then log him in with that password and force him to change it immediately.
#Valentin Mezev:
Use account Admin getLdapContext, use this context to change password of another account.
Example:
LdapContext context = getLdapContext(url, dn_admin, pass_admin);
context.modifyAttributes(dn_change, modificationItems);

JLDAP for Authentication

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

Categories

Resources