Need password reset example code

Jul 30, 2012 at 10:21 AM

Hello everyone,

I want to reset the user password using FIM resource management client.
To achieve this, it needs to cover below scenarios in FIM resource management client
1. Check user is registered for password reset
    If user is not registered then register user for password reset
2. Fetch the challenge questions and answer it.
3. After answering all challenges, do actual change password 

Demo example provided with FIM resource management client is somehow not working for my objective, it will be appreciated if someone guide me or provide the demo code to achieve my objective.  In addition, I need help If I missing any scenario to cover the objective.
I will look forward for help.

Thanks,
Rahul

Aug 2, 2012 at 1:48 PM

What type of Client application are you planning on writing? Will this be a Windows Form/Console application a remote service or a web based app executing remotely or on a FIM Portal server? You'll need to be authenticated to register but anonymous when performing the actual password reset. Both require a bit of handshaking to establish the correct context. Client type and Client location will determine how you authenticate, and if you should use impersonation or kerberos delegation when connecting to the different endpoints.

Aug 3, 2012 at 10:53 AM

First of all thanks for your reply!!

Ours is windows standalone application which can be on a remote box. Basically we want to achieve self-service and help desk admin password resets .We are using Alternate End Point for this. We want more details on how this handshaking is done (may be sample code) to establish context. We do have FIM Admin credentials and want to know if there is a way we can do  impersonation stuff.

Aug 3, 2012 at 9:50 PM

Since this will be a Windows Form application running on a networked client, you won't need to do any impersonation because the DefaultClient will already add your Default Network Credentials to the request. This will work for the password reset registration piece, because you must be authenticated in order to perform the registration. You can also enumerate the current user to see if they have completed the registration and prompt them for the questions, like the FIM client tool does already. The example code already does get the list of questions for the current user... let me know where you see it failing.

Password reset would not make sense if you are already logged in to the account you are trying to reset, and for this reason, you must be the anonymous user to perform this action.

Aug 9, 2012 at 1:47 PM

Hi Mike,
Thanks for your reply!

Yes, I am using anonymous user credentials to change the password of other user.
Currently I have generated security token and I am successful in generation of “AnonymousInteractionRequiredFault”.

I have implemented the “Create” method for WsTransferClient.
Password reset soap message is created and passed to ‘WsTransferClient .Create’ request.
The method ‘WsTransferClient .Create’ also uses security token for WsTransferClient client.

I am getting below fault when I pass password reset soap message to ‘channel.Create(request)’
“There is no context attached to incoming message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the incoming binding supports the context protocol and has a valid context initialized.”

Not sure whether I am in right direction. I need your help to resolve this obstacle .
Below is my message request. Do I need any changes in soap message?

{<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action>
  </s:Header>
  <s:Body>
    <PWResetRequestData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <NewPassword>TABvAGcAaQBjADMAMgAxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</NewPassword>
    </PWResetRequestData>
  </s:Body>
</s:Envelope>}

Thanks,
Rahul

Aug 10, 2012 at 2:42 AM

You'd need to know the answers to the QAGate questions.  Here is an overview of the communications that occur during the process:

Start the process by setting ResetPassword = true on the Person resource. This will throw an AuthenticationRequiredFault.

From the AuthenticationRequiredFault Detail you grab the SecurityTokenServiceAddress and the response Context.

Create a SecurityTokenServiceClient , from the previous Context.. BuildRequestSecurityTokenMessage using the InstanceID contained in the Context.

Send this RSTM to RequestSecurityToken and get the RequestSecurityTokenResponse.

The response will contain the QAGate challenge questions.

Grab the answers to the questions and put them in a AuthenticationChallengeResponse, then pass that back to the BuildRequestSecurityTokenResponseMessage and send the message via RequestSecurityTokenResponse.

Check for the Response.IsFault to determine if the answers match. If so GetContextTokenFromResponse.

Via the AlternateClient, Put the message using the token from RSTR.

Trap for a AnonymousInteractionRequiredFault. Get the endpoint address from the fault detail. Get the InstanceID to build a new ContextMessageProperty.

Build a ContextualSecurityToken from your previous authNSecurityToken and the fault InstanceID.

CreateMessage using your security token and your PWResetRequestData. Get the Response from the client.Create.

Check for Response.IsFault... if false, your password has been reset successfully.

Is this what you are asking for?

Aug 10, 2012 at 1:41 PM

Thanks Mike for follow up! Your reply has really helped.

Now the problem is:
I can reset password of an account only if use login credential for the same account.
   For example:
     If ‘Jsmith’ is an account and I want to change a password of ‘JSmith’.
     In this case change password successfully happens only if I use the client credential of ‘JSmith’
     If I use ‘Administrator’ credential for client then password reset for ‘JSmith’ fails with fault “Security check failed”
     I don’t know whether it is correct behaviour or not?

As you said “Password reset would not make sense if you are already logged in to the account you are trying to reset, and for this reason, you must be the anonymous user to perform this action”
But in my case I logged in with ‘JSmith’ credential I can do reset password of ‘JSmith’.
I don’t know how this is happing? Do I need any configuration changes in FIM portal?

I am not clear about anonymous user, how to create anonymous user. Can you elaborate this?
How can I achieve password reset using anonymous account credentials?

Thanks,
Rahul

Aug 10, 2012 at 3:30 PM

The FIM web service will assign any user that it does not manage to the Anonymous User credentials.  This is a built-in user with a static resource identifier.

The PWResetActivity grants access to the endpoint to two users, Anonymous and the user who is trying to reset their password. On connection, FIM performs a SID lookup of the credential and matches it with SIDs contained in the FIM store.  If no match, the user is Anonymous.

You may want to impersonate an account that is not managed by FIM, like Network Service Account so FIM always makes your connection Anonymous.

Aug 13, 2012 at 3:13 PM

Thanks Mike,

That was helpful !!
Now I have completed the reset password implementation.

-Rahul