Implementing (Parts Of) ASP.NET Identity Using F#

I started working though this and this article for implementing security in a new Web Api 2 site I am spinning up.  Everything is working out OK – not great but better than prior ASP.NET implementations I have done.  I do think the ASP.NET team has made security better and I am really excited about token based security.  My biggest gripe is that there is still too much magic going on and it is still hard to introduce non-out of the box implementations.  For example, the sample code that you can add via Nuget has a placeholder for en email provider.  The article has the code for a specific implementation of a company called SendGrid (the sample is here and the email is here).
The CSharp implementation looks like this (I did add some constructor injection b/c I am opposed to touching the Configuration (or any part of the file system for that matter) outside of Main on sanity grounds):
1 public class SendGridEmailProvider: IIdentityMessageService 2 { 3 String _mailAccount = String.Empty; 4 String _mailPassword = String.Empty; 5 String _fromAddress = String.Empty; 6 7 public SendGridEmailProvider(String mailAccount, String mailPassword, String fromAddress) 8 { 9 _mailAccount = mailAccount; 10 _mailPassword = mailPassword; 11 _fromAddress = fromAddress 12 } 13 14 public System.Threading.Tasks.Task SendAsync(IdentityMessage message) 15 { 16 var sendGridMessage = new SendGridMessage(); 17 sendGridMessage.From = new MailAddress(_fromAddress); 18 List<String> recipients = new List<string>(); 19 recipients.Add(message.Destination); 20 sendGridMessage.AddTo(recipients); 21 sendGridMessage.Subject = message.Subject; 22 sendGridMessage.Html = message.Body; 23 sendGridMessage.Text = message.Body; 24 25 var credentials = new NetworkCredential(_mailAccount, _mailPassword); 26 var transportWeb = new Web(credentials); 27 if (transportWeb != null) 28 return transportWeb.DeliverAsync(sendGridMessage); 29 else 30 return Task.FromResult(0); 31 } 32 }

I then decided to implement a SMS Text Provider along the same lines.  The 1st company I came to was CDyne but when I went to their sample code, they are still using a SOAP-based service and the last thing I wanted to do was to clutter up my project with all of the WSDL and files that you needs when consuming a service like that.
I then thought, this is stupid.  I might was well use FSharp type providers to do the implementation.  Less Code, less files, less clutter, more goodness.  I first swapped out the Email to a FSharp implementation:
1 type SendGridEmailService(account:string, password:string, fromAddress:string) = 2 interface IIdentityMessageService with 3 member this.SendAsync(identityMessage) = 4 let sendGridMessage = new SendGridMessage() 5 sendGridMessage.From = new MailAddress(fromAddress) |> ignore 6 let recipients = new List<string>() 7 recipients.Add(identityMessage.Destination) 8 sendGridMessage.AddTo(recipients) 9 sendGridMessage.Subject <- identityMessage.Subject 10 sendGridMessage.Html <- identityMessage.Body 11 sendGridMessage.Text <- identityMessage.Body 12 13 let credentials = new NetworkCredential(account, password) 14 let transportWeb = new Web(credentials) 15 match transportWeb with 16 | null -> Task.FromResult(0):> Task 17 | _ -> transportWeb.DeliverAsync(sendGridMessage)

I then did a SMS text provider using type providers.
1 type cDyneService = Microsoft.FSharp.Data.TypeProviders.WsdlService<"http://sms2.cdyne.com/sms.svc?wsdl"> 2 3 type CDyneSMSService(licenseKey:Guid) = 4 interface IIdentityMessageService with 5 member this.SendAsync(identityMessage) = 6 let cDyneClient = cDyneService.Getsms2SOAPbasicHttpBinding 7 let client = cDyneService.Getsms2SOAPbasicHttpBinding() 8 match client with 9 | null -> Task.FromResult(0):> Task 10 | _ -> client.SimpleSMSsendAsync(identityMessage.Destination,identityMessage.Body,licenseKey):> Task

Compared to a CSharp implementation, this is joyous.  Less noise, more signal.  And thanks to Lee on Stack Overflow for helping with the upcast of Task…

One Response to Implementing (Parts Of) ASP.NET Identity Using F#

  1. Pingback: F# Weekly #47, 2014 | Sergey Tihon's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: