Building the FIM 2010 R2 SmsServiceProvider.dll

When using Self-Service Password Reset (SSPR) in FIM 2010 R2 it is a common request from my customers to use SMS OTP (One-Time Password) to authenticate the user trying to reset his password.

In one of my earlier posts, Automate SSPR registration in FIM 2010 R2, I described how you can automate the registration process. But in order to use SMS OTP you also need to build a small dll file. At Microsoft TechNet you can find an example on how to build the required SmsServiceProvider.dll.

The problem is that there is a “bug” in the FIM Service that makes it easy to build the dll in a way that does not work. The error you will run into is shown in the eventlog as “System.TypeLoadException: The custom SMS provider DLL does not implement the required interface.“.

The dll is required to have a class that implements the Microsoft.IdentityManagement.SmsServiceProvider.ISmsServiceProvider interface and that class should have a public method called SendSMS as seen in the code snippet below.

namespace XPServices.FIM.SmsServiceProvider
{
    using System;
    using System.Collections.Generic;
    using Microsoft.IdentityManagement.SmsServiceProvider;

    public class SmsServiceProvider : ISmsServiceProvider
    {
        public void SendSms(string mobileNumber, string message, Guid requestId, Dictionary<string, object> deliveryAttributes)
        {
            XPServices.FIM.mySMSProvider.SendSms(mobileNumber, message);
        }
    }
}

When the FIM Service looks at the dll it requires that the ISmsServiceProvider is the FIRST interface. If your SMS service provider uses for example a Web Service and you add the reference to that Web Service in your code it will likely show up first and the FIM Service will give you the error “System.TypeLoadException: The custom SMS provider DLL does not implement the required interface.

The solution is to move all logic and references into a separate class library. As you see in my code above all logic about how to send the SMS is moved into the XPServices.FIM.mySMSProvider class. This will hold the references to any Web Services and FIM Service will not have any trouble enumerating the SmsServiceProvider.dll since it only holds one class and one method. Below is a snippet showing parts of a typical class library in this scenario.

namespace XPServices.FIM
{
    public class mySMSProvider
    {
        static string id;
        static string password;

        public static string SendSms(string userMobileNumber, string message)…
        public static void GetSMSConfig()…
     }
}

When deploying this all we need to do is drop both dll’s in the FIM Service folder (default this is C:\Program Files\Microsoft Forefront Identity Manager\2010\Service\)

14 Replies to “Building the FIM 2010 R2 SmsServiceProvider.dll”

  1. James

    Hi,

    Great article. Im actually looking to use FIM 2010R2 to send an OTP via email. The thing is that we want to send it to a email to sms gateway so we want the front end to tell the user they are getting send a txt.

    Can either the SMS Gate handle this by sending this to the users smsOTP number + @example.com

    or is there a better way.

    Reply
    • Kent Nordström Post author

      Since you are in charge of the action in SmsServiceProvider.dll you can code it to do what you like. But I am not 100% sure what you are aiming at.

      Reply
    • Jason

      I second James idea. May not all users have mobile or wanna expose mobile to corporate directory. I am also looking for a way to send same OTP to both SMS/Email. Unfortunately current workflow can only send different OTP to different gate.
      I don’t think it can be done by customizing the smsprovider.dll code as email gate is another activity in AuthenticationN workflow.

      Reply
  2. aman khanna

    the second code which is wriiten has to be implemented and can u please guide whr exaclty we need to build this dll and how the flow will be actually.

    Thanks,
    Aman

    Reply
    • Kent Post author

      I’m afraid I don’t really understand. Your prodvider should be able to give you some simple code samples on how to use their service. And then all you need is to put that into the dll. If it’s a web service that you need to reference make sure you read my post carefully and maybe split your code into two dlls as I explained.

      Reply
      • Bharath

        Yes
        Thank You
        I achieved SMS after adding web proxy code line.
        Now the challenege is based on the username or logged in user or based on mobile number can we get email. So that along with sms I also want to send an email. Please help me out

        Reply
  3. Shane

    Is it possible to provide a dll that uses a “virtual” mobile?
    We have SMS devices installed on the network using sx virtual link and would prefer to use those.
    The other method is to send an email to our provider that lands up as a SMS.

    Reply
    • Kent Post author

      You can basically call wathever api you like in the smsserviceprovider.dll as long as the code ends up on a device you “know” is owned by the user. When SMS gateway uses SMTP (mail) i sometimes use the MailOTPGatewaay but changes the labels to look like SMS. Most of thoose customers have internal source for mobile phone number and SSPR registration is automated in FIM/MIM.

      Reply
  4. Vitaly

    Hello!

    If my sms library using web services and for correct working I need to specify web service endpoint and binding.

    Where I can specify these config settings?

    Thanks in advance!

    Reply
    • Kent Post author

      It’s up to you to store any kind of configuration your smsserviceprovider.dll needs. There is no “special” place within FIM/MIM to store that kind of configuration.

      Reply
  5. Imran

    HI Kent,

    I am getting the format error continuously.

    mscorlib: System.FormatException: Input string was not in a correct format.
    at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
    at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
    at System.Convert.ToInt32(String value, IFormatProvider provider)
    at Microsoft.IdentityManagement.Samples.mySMSProvider.SendSms(String userMobileNumber, String message)
    at Microsoft.IdentityManagement.Samples.SmsServiceProvider.SendSms(String mobileNumber, String message, Guid requestId, Dictionary`2 deliveryAttributes)
    at Microsoft.IdentityManagement.SmsServiceProvider.SmsServiceProviderManager.SendSms(String mobileNumber, String message, Guid requestId, Dictionary`2 deliveryAttributes)
    at Microsoft.ResourceManagement.Workflow.Hosting.SmsNotificationServiceImpl.SendSmsMessage(String mobileNumber, String message, Guid requestId, Dictionary`2 deliveryAttributes)
    at Microsoft.ResourceManagement.Workflow.Activities.OneTimePasswordSmsAuthenticationGate.SendOneTimePassword(String plainTextOneTimePassword)

    I have tried different stuff and using the two dlls as well. I suppose there is an issue somewhere else here. Can you help me out here.

    Thanks

    Reply
    • Kent Post author

      Sorry for the late response… All I can think of is that you, as the error indicates, are trying to use a StringToNumber function on a string that cannot be translated. Usually all telephone numbers should be handled as strings not as numbers.

      Reply

Leave a Reply to Kent Cancel reply

Your email address will not be published. Required fields are marked *