Posts tagged FIM
Posts tagged FIM
25 notes &
The answer to “Why doesn’t my FIM Workflow Activity work inside of a loop?”
2 notes &
Just noticed the documentation was incorrect for the RCDC in FIM. Here’s what it hsould be
In FIM 2010, it can be helpful to make some regular expressions case insensitive. You can ignore case within a group by using ?!:. For example, for Employee Type, use the following:
^(?i:contractor|full time employee)$
The incorrect version was ^(?!:contractor|full time employee)%
27 notes &
I thought I posted the follow up but must’ve got sidetracked.
Scenario:
User John does an update request on John.Manager => launches authorization workflow, which uses the public client to create a request to the middle tier on John’s behalf?
If you enable delegation on your public proxy WCF bindings, you can in your activities impersonate the user credentials with this call:
(actually, you may only need to be impersonation since you’re impersonated call never leaves the box to talk to the fim service)
ServiceSecurityContext.Current.WindowsIdentity.Impersonate();
Then, if you use the public client in your code to make calls to the fim service, you will be under that user’s credentials and can kick off other necessary MPRs.
Couple of salient points:
1. All code that follows that impersonation call will be under the users credentials. Makes sense right? So what happens if you have a create activity or an update activity in your workflow? It fails b/c that thread is under the user context so any connections to the sql fim store to run any sprocs will fail b/c that user doesn’t have access to the DB.
2. ServiceSecurityContext is backed by a [ThreadStatic] attribute. ThreadStatic means an variable is scoped only to the current thread. Which means if you fork a new thread, that context is lost. So why does this matter to us? Well, when workflows passivate or get persisted to the DB (ex: when an activity is waiting on input from an approver), that context gets lost. So when your code comes back up, you no longer have access to ServiceSecurityContext.
3. If you’re under the impersonated context when the workflow passivates….wild things may happen. Haven’t tested it.
4. You no longer have parenting of requests. There are no longer chains of requests so if you cancel a parent request, the new request you spawned may
5. You have to handle the logic of how to wait on the new request you just spawned: does your activity proceed if there’s an authz workflow kicked off? Does it wait on the input? What if there’s an authn workflow? Does it handle the child requests interactive action workflows? Yup, it’s very nasty and hairy to solve in the general case (there is a reason why the FIM team doesn’t have this enabled by default)
Here’s what I would suggest (haven’t had time to fully explore this, just used this to implement delegation as a proof of concept):
1. Store the WindowsIdentity locally when overriding OnActivityExecutionLoad
2. Have very simple defined cases of when you kick off requests that spawn new AuthZ workflows. Don’t try to solve the general case. Any case that requires chainign of requests => pain
3. Keep the impersonation scope very limited and defined:
using(ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
{
//Code to call public client to talk to FIM service
}//Impersonation is always reverted this way
4. For auditing/reporting, the child request that gets created this way will have the user as the actorID. Just be aware.
27 notes &
First, let it be known that I hate xml config files. It’s a pain in the ass to write a script to modify certain portions of it…like when I want to turn off or turn on tracing in the FIM portal or the RMS. So I usually resort it to doing it by hand….which is terrible because I always forget small details.
Like why is message logging not happening? Oh yeah. Have to add this tag:
<system.serviceModel>
<diagnostics wmiProviderEnabled=”true”>
<messageLogging
logEntireMessage=”true”
logMalformedMessages=”true”
logMessagesAtServiceLevel=”true”
logMessagesAtTransportLevel=”true”
maxMessagesToLog=”3000”
/>
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior name=”Default”>
<serviceDebug includeExceptionDetailInFaults=”true”/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.diagnostics>
<sources>
<source name=”System.ServiceModel.MessageLogging” switchValue=”Verbose,ActivityTracing”>
<listeners>
<add type=”System.Diagnostics.DefaultTraceListener” name=”Default”>
<filter type=”” />
</add>
<add name=”DiagnosticListener”>
<filter type=”” />
</add>
</listeners>
</source>
<source name=”System.ServiceModel” switchValue=”Information,ActivityTracing” propagateActivity=”true”>
<listeners>
<add type=”System.Diagnostics.DefaultTraceListener” name=”Default”>
<filter type=”” />
</add>
<add name=”DiagnosticListener”>
<filter type=”” />
</add>
</listeners>
</source>
<source name=”Microsoft.ResourceManagement” switchValue=”Verbose,ActivityTracing” propagateActivity=”true”>
<listeners>
<add type=”System.Diagnostics.DefaultTraceListener” name=”Default”>
<filter type=”” />
</add>
<add name=”DiagnosticListener”>
<filter type=”” />
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData=”C:\logs\FIMPortal.Client_tracelog.svclog” type=”System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”
name=”DiagnosticListener” traceOutputOptions=”LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack”>
<filter type=”” />
</add>
</sharedListeners>
<trace autoflush=”true” />
</system.diagnostics>
0 notes &

I published all the source code for the OTP Demo I did over at TEC at https://github.com/ikrima/Public-Development
The source code contains a sample password reset activity using the interactive activity, the SMS One Time Password Authentication activity, an aspx web app that allows you to perform web based password reset, and the necessary public client extensions that allow you to talk to interactive activities (it would be easy to extend it to communicate to the OOB Password Reset Activity)
19 notes &
So I’m speaking at The Experts Conference (TEC) this year in vegas. I have two presentations and as I’m wrapping up writing them, I realized that there’s just way too much content for two one hour presentations. So I carved out the important bits but I figured I’d ask the interweb about the rest: what would you like an emphasis on?
Presentation 1: How to write custom authentication activities in FIM (e.g. OTP)
- Writing GINA Win32 UI (so your activity shows up in GINA)
-Extending the public client to talk to authentication activities for password reset
-Writing interactive activities (e.g. a non-password reset activity)
Presentation 2: Delegation model in FIM
- Which example should we work through: Approve on Behalf of vs. Password Reset on behalf of (It admin resets the password of another user)
-Go into detail about extending the public client to talk to interactive activities
-How to write activities invoke authorization workflows on the user’s behalf (impersonation)
0 notes &
The FIM webservice is multithreaded so each new client request has its own request and request state (SQL is the persistence store that’s used). So the number of active “requests” is limited to whatever your WCF configuration binding dictates (you can set maximum number of simultaneous TCP/IP connections, maximum timeout, maximum payload, etc etc etc). These configuration parameters dictate how many active connections you have, as opposed to requests in the system. Now each request may spawn off AuthN, AuthZ, or Action Workflows. And those workflows are run in parallel by the Workflow Engine. AuthN workflows run in their own “context” and they are synchronous to each request. For example, if Ikrima requests to join BillG’s Direct Reports and he kicks off 2 authentication workflows and at the same time, Frank requests to join Administrator’s Group and he kicks off an AuthN workflow, what will happen? Well both requests will happen at the same time b/c the webservice is multi-threaded. So here’s a timeline view Ikrima Join Group Authenticate to AuthN Workflow 1 Authenticate to AuthN Workflow 2 Continue processing Frank Join Group Authenticate to AuthN Workflow 2 Continue Processing So the webservice sequentially processes AuthN workflows in the context of one request. Now what about AuthZ/Action workflows? Well those are asynchronous. Suppose Ikrima joins BillG’s group and he kicks off an Email Notification workflow and an Approval Workflow. And suppose Frank does that at the same time. What does that look like? Ikrima Join Group Approval Workflow Gets Kicked Off <—-Notice, they get kicked off at the same time Email Notification Workflow Gets Kicked off <—-Notice, they get kicked off at the same time Frank Join Group Approval Workflow Gets Kicked Off <—-Notice, they get kicked off at the same time Email Notification Workflow Gets Kicked off <—-Notice, they get kicked off at the same time So how many workflows do we have in flight in the AuthN scenario? 2 at most. Ikrima’s AuthN Workflow 1 & Frank’s AuthN Workflow 1. What about AuthZ? 4. Ikrima & Frank’s Approval & Email workflows. And now how many workflows can we have inflight at the same time? Well, those are determined by configuration parameters So why is there a different maxSimultaneousAuthenticationWorkflows & maxSimultaneousAuthorizationAndActionWorkflows? Well, remember that Authorization/Action workflows can be long-running and are asynchronously invoked. For example, the approval activity needs to wait on a manager to approve a request. But, the approval activity doesn’t need to be running and in memory the entire time. So, it can passivate (aka store itself & state to SQL) and then the workflow engine can go off and process another workflow. Authentication activities are a different matter. We need a response right now; imagine if when logging in or resetting your password, you were stuck waiting on a manager’s approval to authenticate yourself. So, because of this, authentication workflows never passivate which is why I said earlier, you would have a problem trying to get 70k users registering at the same time. As far as how many longstanding requests are in the system, well, you can have as many as your system handles it (and maybe there are some other configuration parameters that cull out expired requests too).
0 notes &
This has been frustrating me for a couple of days since I couldn’t find a supported way of doing it, so I finally just found a way to use reflection to poke deep into some dataexchanges. Use at your own risk, as this is not supported. protected override void OnActivityExecutionContextLoad(IServiceProvider provider) { if (this.baseAddresses == null) { Type hostActivationServiceInteralType =typeof(Microsoft.ResourceManagement.AuthenticationWorkflowMode).Assembly.GetType(“Microsoft.ResourceManagement.Workflow.Runtime.HostActivationService”); hostActivationServiceInternalObject = provider.GetService(hostActivationServiceInteralType); var propertyInfo = hostActivationServiceInternalObject.GetType().GetProperty(“BaseAddresses”, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (propertyInfo != null) { ReadOnlyCollection<Uri> result = propertyInfo.GetValue(hostActivationServiceInternalObject, null) as ReadOnlyCollection<Uri>; this.baseAddresses = new List<string>(); if (result != null) { foreach (Uri baseAddress in result) { if (baseAddress.AbsoluteUri.StartsWith(“http:”,StringComparison.OrdinalIgnoreCase)) { this.baseAddresses.Add(baseAddress.AbsoluteUri); } } } }
In your activity, you write:
1 note &
To do this bulk load, you have to understand how the FIM engine stores authentication information. To make this simple, let’s use the User Ikrima as our user, the default QA Activity as the authentication activity, and the default authentication workflow as our example (but you can generalize to everything else)
So, to programmatically register Ikrima, you would need to insert the GUID of the default AuthN Workflow (9c3aca59-a85c-437f-bb67-9ce5a70521d7) into Ikrima.AuthNWFRegistered
So what goes inside a GateRegistration Object? Well, here are the attributes you need to fill
<ns0:AuthenticationGateActivity ValidationError="{x:Null}" x:Name="authenticationGateActivity3" RegistrationData="{x:Null}" ChallengeResponse="{x:Null}">
<ns0:AuthenticationGateActivity.AuthenticationGate>
<ns0:QAAuthenticationGate ResponseTimeout="00:05:00" NumQsReqCorrectAns="3" NumQsReqRegistration="3" NumQsRandomPresented="3" NumQsDisplayedForReg="3" ValidationError="{x:Null}">
<ns0:QAAuthenticationGate.Questions>
<x:Array Type="{x:Type p9:String}" xmlns:p9="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Customized Question 1</ns1:String>
<ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Question Custom 2</ns1:String>
<ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">The 3rd question</ns1:String>
</x:Array>
</ns0:QAAuthenticationGate.Questions>
</ns0:QAAuthenticationGate>
</ns0:AuthenticationGateActivity.AuthenticationGate>
</ns0:AuthenticationGateActivity>
You can see, the Activity name is “authenticationGateActivity3”.
0 notes &
Alright, after a couple of hours of troubleshooting a customized deployment, I found the probable cause. This fault is what’s returned from any activity that uses the XmlInteractiveActivity (e.g. Password Reset, Approval activity, etc) when validation fails. When a client talks to these activities, it talks to them directly through an endpoint they create. In my case, we were talking directly to the Password Reset activity. The PWResetActivity gives access to its endpoint to two users (Anonymous & the user who’s trying to reset his password). But, how does it determine if a user is anonymous? Now when would this be problematic? Same thing happens if you have a custom client that’s talking to the endpoints directly running under an account that’s in the FIM Store. This is not necessary when communicating with the FIM Service endpoint because it stamps any request coming in through the alternate endpoint as anonymous, regardless of the windows credentials attached to your request. Why is this layer necessary?
Well, it does a sid lookup of the credentials coming in and matches it with sids in the FIM store.
If there’s no match, it stamps the identity as Anonymous.
Well, if you set the identity of the PwdMgmtProxy.exe service to a FIM Account, every request to reset password will happen in that FIM Account’s context.
And every password reset will fail.
Well when you get to the password reset endpoint, it’s a separate interactive workflow endpoint, created by the receive activity.
So without this layer, any user can talk to that endpoint to reset the password of users going through this workflow.