Password Reset/AlternateEndpoint Client/stsClient

Developer
Apr 10, 2010 at 6:33 PM

Hi everyone,

I just wanted to start a discussion about the upcoming changes to support the above functionality.

I have not uploaded these changes yet. I am waiting to make sure that other changes are stable before integrating the code.

To summarize the changes to the client to support the above functionality:

1 - I fleshed out the implementation of the alternateEndpoint client and added one to the default client

2 - I added an stsEndpoint client to the solution and added one to the default client

3 - I modified the Put methods for the default client to support ContextualSecurityToken objects and ContextMessageProperty parameters

4 - I modified the Put method so it can handle a useAlternateEndpoint parameter - this is used to tell the Default Client to use the Alternate endpoint

5 - I modified the behavior of the endpoint channels so that automatic context management is disabled

6 - I modified the Put function so that the putResponse is provided as an out parameter - this is necessary to be able to examine the response before the call to HandleFault is made.

7 - I modified the Put function so that if an AuthenticationRequiredFault is returned, we can gather the context of that response and then make a call to HandleAuthenticationFault

8 - HandleAuthenticationFault will start a conversation with the STS and attempt to get a security Token for the customer. The only kind of authentication we understand right now is a QAGate

9 - If a QAGate is detected, we will call a delegate to ask QA questions. If no delegate is registered, we will throw an exception.

10 - I have included a sample QAGateQuestionAsker. This can be registered as a delegate to the Default Client to handle asking questions.

11 - The QAGateQuestionAsker uses events every time it wants to ask a question.

12 - I have included a sample PasswordResetTesting console app. This app makes a simple call to the Default Client for ResetPassword. It also includes a few functions that handle the events from the QAGateQuestionAsker and will prompt the user for Challenge/Response questions on the console.

13 - Finally, there is a new method in the Default Client called reset password. This will send a Put to the Alternate Endpoint to initiate the Password Reset function

There is a final step to this process: If there is an ActiveDirectoryPasswordReset activity in the Action Phase of the password reset mpr (as is the case in the default install) then an additioanl information required fault is issued. Form there, we need to Put the new password to the endpoint found in this fault. I have not gone to this step because my current scenario does not include having the user provide the new password. I will add this over the next few weeks as time allows.

For now, I am waiting to hear back from Paulo as to the best time to merge these changes into the current code. Feel free to comment on the above in the interim.

 

-Jeremy

Developer
Apr 12, 2010 at 2:48 AM

OK, Changes are posted!

Apologies to Paulo, I reverted some of his style changes merging in the original IdM Team client. I figured out a "better" way to merge about about half way through.

Changes are in this Changeset:

http://fim2010client.codeplex.com/SourceControl/changeset/view/1984a78d6af7

 

-Jeremy

Jun 24, 2010 at 5:27 AM
while implementing the code.. ContextualSecurityToken objects and ContextMessageProperty parameters These parameters are not identified..no class defination.. how can we get them.. ??
Oct 29, 2010 at 5:08 PM
Edited Oct 29, 2010 at 7:05 PM

Jeremy,

This is Gary (the guy who posted the update to the 'Put' method in case no changes would be made), and I am working on a Password Reset implementation.  I've been testing the solution and doing my usual 'If I pass in bad info, what happens' testing.  If I pass in an invalid domain or user, I get an 'endpoint' or 'unwillingtoperform' fault.  If I get this message, is it safe to assume that either the domain/username is invalid?  If I look at the raw soap request, there is a response, but it is encrypted.  Is there a way to decrypt to get a better message?

Also, if the questions are answered incorrectly, the "Received a response from STS that we do not understand" exception is thrown.  The RSTR.IsFault property is set to true.  If so, can it be assumed that the questions were not correctly answered?

Let me know if what I'm asking isn't clear.  As with the last item, if there is anything that would be helpful for me to code, I'm more than happy to do so.

EDIT: I will probably lose any credibility with this question, but I am struggling with how to create the new password message, after the questions have been answered correctly and the AnonymousInteractionRequiredFault exception is caught. It makes sense that you'd need to use that endpoint because it is associated with the workflow. But I don't see how to properly create it.

Thanks,

Gary

Nov 3, 2010 at 3:28 PM

@Gary

After the AnonymousInteractionRequiredFault, you'll need to create a PWResetRequestData object and assign the newPassword property:

byte[] newPassword = new byte[512];
byte[] bytePwd = System.Text.Encoding.Unicode.GetBytes( newPasswordString );
Array.Copy(bytePwd, newPassword, bytePwd.Length);
PWResetRequestData data = new PWResetRequestData();
data.NewPassword = newPassword;

Clone the current WsTransferClient:

WsTransferClient clientCopy = new WsTransferClient( 
new
ClientMultipleTokenBinding(),
new
EndpointAddress(new Uri(workflowInteractionEndpoint), this.wsTransferClient.Endpoint.Address.Identity, this.wsTransferClient.Endpoint.Address.Headers));

Finally, you'll need to send a Create message containing the password data.  The Create method doesn't exist in the current client, but you can mimic the Put method and call a channel.Create(..) method instead of the channel.Put(..):

Message response2 = clientCopy.Create(Message.CreateMessage(clientCopy.Endpoint.Binding.MessageVersion,
   Constants.WsTransfer.CreateAction,
   data,
   new ClientSerializer(typeof(PWResetRequestData))),
   securityToken);

You will need to build the securityToken from the previous AnonymousInteractionRequiredFault.

Hope this helps,

- Mike

Developer
Nov 3, 2010 at 4:00 PM

Yep, we did this.

Thanks!

From: mgercevich [mailto:notifications@codeplex.com]
Sent: Wednesday, November 03, 2010 7:29 AM
To: jeremy@palenchar.net
Subject: Re: Password Reset/AlternateEndpoint Client/stsClient [fim2010client:208916]

From: mgercevich

@Gary

After the AnonymousInteractionRequiredFault, you'll need to create a PWResetRequestData object and assign the newPassword property:

byte[] newPassword = new byte[512];
byte[] bytePwd = System.Text.Encoding.Unicode.GetBytes( newPasswordString );
Array.Copy(bytePwd, newPassword, bytePwd.Length);
PWResetRequestData data = new PWResetRequestData();
data.NewPassword = newPassword;

Clone the current WsTransferClient:

WsTransferClient clientCopy = new WsTransferClient( 
new
ClientMultipleTokenBinding(),
new
EndpointAddress(new Uri(workflowInteractionEndpoint), this.wsTransferClient.Endpoint.Address.Identity, this.wsTransferClient.Endpoint.Address.Headers));

Finally, you'll need to send a Create message containing the password data. The Create method doesn't exist in the current client, but you can mimic the Put method and call a channel.Create(..) method instead of the channel.Put(..):

Message response2 = clientCopy.Create(Message.CreateMessage(clientCopy.Endpoint.Binding.MessageVersion,
   Constants.WsTransfer.CreateAction,
   data,
   new ClientSerializer(typeof(PWResetRequestData))),
   securityToken);

You will need to build the securityToken from the previous AnonymousInteractionRequiredFault.

Hope this helps,

- Mike

Read the full discussion online.

To add a post to this discussion, reply to this email (fim2010client@discussions.codeplex.com)

To start a new discussion for this project, email fim2010client@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Nov 17, 2010 at 7:08 PM

Hi Guys,

I got pulled onto another project for a while, and I must have forgotten to flag to be emailed, so I didn't see these responses.  Thanks, that's exactly what I'm looking for!

 

Gary

Feb 10, 2011 at 7:33 AM

Hi everyone,

I m trying to use this client, i am getting to the same problem as Gary was gettin i.e creating pwd reset create mesg, trying the above code that is probably the solution for Gary i.e. as follows,

Finally, you'll need to send a Create message containing the password data.  The Create method doesn't exist in the current client, but you can mimic the Put method and call a channel.Create(..) method instead of the channel.Put(..):

 

Message response2 = clientCopy.Create(Message.CreateMessage(clientCopy.Endpoint.Binding.MessageVersion,
   Constants.WsTransfer.CreateAction,
   data,
   new ClientSerializer(typeof(PWResetRequestData))),
   securityToken);

 

I have build the Create method like this in WstransferClient,

public Message Create(Message request, SecurityToken token)
        {
            WsTransferClient client = new WsTransferClient(
                new ClientMultipleTokenBinding(),
                this.Endpoint.Address);

            client.Endpoint.Behaviors.Remove(typeof(ClientCredentials));
            client.Endpoint.Behaviors.Add(new TokenAndClientCredentials(token));

            client.ClientCredentials.Windows.ClientCredential = this.ClientCredentials.Windows.ClientCredential;

            IResource channel = client.ChannelFactory.CreateChannel();
            IContextManager contextManger = ((IClientChannel)channel).GetProperty<IContextManager>();
            contextManger.Enabled = false;

            using (channel as IDisposable)
            {
                return channel.Create(request);
            }
        }

 but in response of this Create, getting fault "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"

What i m doing wrong here or how to fix that?


Mar 2, 2011 at 3:50 PM

You need to pass in the SecurityToken that is returned from the AnonymousInteractionRequiredFault.  This is the only way to re-attach into the workflow to perform the Reset.