{"id":2264,"date":"2012-08-23T08:29:48","date_gmt":"2012-08-23T08:29:48","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/2012\/08\/23\/plugging-custom-oauthopenid-providers\/"},"modified":"2012-08-23T08:29:48","modified_gmt":"2012-08-23T08:29:48","slug":"plugging-custom-oauthopenid-providers","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/plugging-custom-oauthopenid-providers\/","title":{"rendered":"Plugging custom OAuth\/OpenID providers"},"content":{"rendered":"<p>In the <a href=\"http:\/\/blogs.msdn.com\/b\/pranav_rastogi\/archive\/2012\/08\/22\/extra-information-from-oauth-openid-provider.aspx\" target=\"_blank\" rel=\"noopener\">previous post<\/a>, I wrote about how you can use the existing providers for Google, Facebook etc. and retrieve extra metadata about the authenticated users. Let\u2019s assume you wanted to change the way the providers request for information. Some examples of this could be<\/p>\n<ul>\n<li>You want to request more data about the user<\/li>\n<li>You want to apply different scope levels when requesting the data<\/li>\n<\/ul>\n<p>This post covers how you can write your own provider and plug it into your ASP.NET web application<\/p>\n<h2>Write your own provider<\/h2>\n<p>Each Provider implements from OpenIdClient. Following example shows a custom implementation of Google Provider which requests information about the user such as firstname\/lastname etc<\/p>\n<p><strong><font color=\"#ff0000\">Please Note<\/font>:<\/strong>&#160; This addresses a bug with the existing google provider which does not return the extra data about the user such as Country\/FirstName\/LastName. The version of google provider is DotNetOpenAuth.AspNet&quot; version=&quot;4.0.3.12153&quot;. We have logged a bug for this and will fix it in next update of this package. <\/p>\n<p>&#160;<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"kwrd\">namespace<\/span> MyApplication<\/pre>\n<pre>{<\/pre>\n<pre class=\"alt\">    <span class=\"kwrd\">using<\/span> System.Collections.Generic;<\/pre>\n<pre>    <span class=\"kwrd\">using<\/span> DotNetOpenAuth.OpenId.Extensions.AttributeExchange;<\/pre>\n<pre class=\"alt\">    <span class=\"kwrd\">using<\/span> DotNetOpenAuth.OpenId.RelyingParty;<\/pre>\n<pre>&#160;<\/pre>\n<pre class=\"alt\">    <span class=\"rem\">\/\/\/ &lt;summary&gt;<\/span><\/pre>\n<pre>    <span class=\"rem\">\/\/\/ Represents Google OpenID client.<\/span><\/pre>\n<pre class=\"alt\">    <span class=\"rem\">\/\/\/ &lt;\/summary&gt;<\/span><\/pre>\n<pre>    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> GoogleCustomClient : OpenIdClient<\/pre>\n<pre class=\"alt\">    {<\/pre>\n<pre>        <span class=\"preproc\">#region<\/span> Constructors and Destructors<\/pre>\n<pre class=\"alt\">&#160;<\/pre>\n<pre>        <span class=\"kwrd\">public<\/span> GoogleCustomClient()<\/pre>\n<pre class=\"alt\">            : <span class=\"kwrd\">base<\/span>(<span class=\"str\">&quot;google&quot;<\/span>, WellKnownProviders.Google) { }<\/pre>\n<pre>&#160;<\/pre>\n<pre class=\"alt\">        <span class=\"preproc\">#endregion<\/span><\/pre>\n<pre>&#160;<\/pre>\n<pre class=\"alt\">        <span class=\"preproc\">#region<\/span> Methods<\/pre>\n<pre>&#160;<\/pre>\n<pre class=\"alt\">        <span class=\"rem\">\/\/\/ &lt;summary&gt;<\/span><\/pre>\n<pre>        <span class=\"rem\">\/\/\/ Gets the extra data obtained from the response message when authentication is successful.<\/span><\/pre>\n<pre class=\"alt\">        <span class=\"rem\">\/\/\/ &lt;\/summary&gt;<\/span><\/pre>\n<pre>        <span class=\"rem\">\/\/\/ &lt;param name=&quot;response&quot;&gt;<\/span><\/pre>\n<pre class=\"alt\">        <span class=\"rem\">\/\/\/ The response message. <\/span><\/pre>\n<pre>        <span class=\"rem\">\/\/\/ &lt;\/param&gt;<\/span><\/pre>\n<pre class=\"alt\">        <span class=\"rem\">\/\/\/ &lt;returns&gt;A dictionary of profile data; or null if no data is available.&lt;\/returns&gt;<\/span><\/pre>\n<pre>        <span class=\"kwrd\">protected<\/span> <span class=\"kwrd\">override<\/span> Dictionary&lt;<span class=\"kwrd\">string<\/span>, <span class=\"kwrd\">string<\/span>&gt; GetExtraData(IAuthenticationResponse response)<\/pre>\n<pre class=\"alt\">        {<\/pre>\n<pre>            FetchResponse fetchResponse = response.GetExtension&lt;FetchResponse&gt;();<\/pre>\n<pre class=\"alt\">            <span class=\"kwrd\">if<\/span> (fetchResponse != <span class=\"kwrd\">null<\/span>)<\/pre>\n<pre>            {<\/pre>\n<pre class=\"alt\">                var extraData = <span class=\"kwrd\">new<\/span> Dictionary&lt;<span class=\"kwrd\">string<\/span>, <span class=\"kwrd\">string<\/span>&gt;();<\/pre>\n<pre>                extraData.Add(<span class=\"str\">&quot;email&quot;<\/span>, fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email));<\/pre>\n<pre class=\"alt\">                extraData.Add(<span class=\"str\">&quot;country&quot;<\/span>, fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.HomeAddress.Country));<\/pre>\n<pre>                extraData.Add(<span class=\"str\">&quot;firstName&quot;<\/span>, fetchResponse.GetAttributeValue(WellKnownAttributes.Name.First));<\/pre>\n<pre class=\"alt\">                extraData.Add(<span class=\"str\">&quot;lastName&quot;<\/span>, fetchResponse.GetAttributeValue(WellKnownAttributes.Name.Last));<\/pre>\n<pre>&#160;<\/pre>\n<pre class=\"alt\">                <span class=\"kwrd\">return<\/span> extraData;<\/pre>\n<pre>            }<\/pre>\n<pre class=\"alt\">&#160;<\/pre>\n<pre>            <span class=\"kwrd\">return<\/span> <span class=\"kwrd\">null<\/span>;<\/pre>\n<pre class=\"alt\">        }<\/pre>\n<pre>&#160;<\/pre>\n<pre class=\"alt\">        <span class=\"rem\">\/\/\/ &lt;summary&gt;<\/span><\/pre>\n<pre>        <span class=\"rem\">\/\/\/ Called just before the authentication request is sent to service provider.<\/span><\/pre>\n<pre class=\"alt\">        <span class=\"rem\">\/\/\/ &lt;\/summary&gt;<\/span><\/pre>\n<pre>        <span class=\"rem\">\/\/\/ &lt;param name=&quot;request&quot;&gt;<\/span><\/pre>\n<pre class=\"alt\">        <span class=\"rem\">\/\/\/ The request. <\/span><\/pre>\n<pre>        <span class=\"rem\">\/\/\/ &lt;\/param&gt;<\/span><\/pre>\n<pre class=\"alt\">        <span class=\"kwrd\">protected<\/span> <span class=\"kwrd\">override<\/span> <span class=\"kwrd\">void<\/span> OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request)<\/pre>\n<pre>        {<\/pre>\n<pre class=\"alt\">            <span class=\"rem\">\/\/ Attribute Exchange extensions<\/span><\/pre>\n<pre>            var fetchRequest = <span class=\"kwrd\">new<\/span> FetchRequest();<\/pre>\n<pre class=\"alt\">            fetchRequest.Attributes.AddRequired(WellKnownAttributes.Contact.Email);<\/pre>\n<pre>            fetchRequest.Attributes.AddRequired(WellKnownAttributes.Contact.HomeAddress.Country);<\/pre>\n<pre class=\"alt\">            fetchRequest.Attributes.AddRequired(WellKnownAttributes.Name.First);<\/pre>\n<pre>            fetchRequest.Attributes.AddRequired(WellKnownAttributes.Name.Last);<\/pre>\n<pre class=\"alt\">&#160;<\/pre>\n<pre>            request.AddExtension(fetchRequest);<\/pre>\n<pre class=\"alt\">        }<\/pre>\n<pre>&#160;<\/pre>\n<pre class=\"alt\">        <span class=\"preproc\">#endregion<\/span><\/pre>\n<pre>    }<\/pre>\n<pre class=\"alt\">}<\/pre>\n<\/div>\n<p>&#160;<\/p>\n<h3>Source Code for existing providers<\/h3>\n<p>The source code for existing providers is public and can be accessed at <a href=\"https:\/\/github.com\/AArnott\/dotnetopenid\/tree\/master\/src\/DotNetOpenAuth.AspNet\/Clients\">https:\/\/github.com\/AArnott\/dotnetopenid\/tree\/master\/src\/DotNetOpenAuth.AspNet\/Clients<\/a><\/p>\n<h2>Register your provider with your application<\/h2>\n<p><strong>WebForms<\/strong><\/p>\n<ul>\n<li>In App_Start\/AuthConfig.cs register the custom provider as follows<\/li>\n<\/ul>\n<div class=\"csharpcode\">\n<div class=\"csharpcode\">\n<pre class=\"alt\">OpenAuth.AuthenticationClients.Add(<span class=\"str\">&quot;Custom Google&quot;<\/span>, () =&gt; <span class=\"kwrd\">new<\/span> MyApplication.GoogleCustomClient());<\/pre>\n<pre><span class=\"rem\">\/\/OpenAuth.AuthenticationClients.AddGoogle();<\/span><\/pre>\n<pre class=\"alt\">   <\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<p><strong>MVC<\/strong><\/p>\n<ul>\n<li>In App_Start\/AuthConfig.cs register the custom provider as follows<\/li>\n<\/ul>\n<p><strong><\/strong><\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"> OAuthWebSecurity.RegisterClient(<span class=\"kwrd\">new<\/span> MyApplication.GoogleCustomClient(),<span class=\"str\">&quot;Google&quot;<\/span>,<span class=\"kwrd\">null<\/span>);<\/pre>\n<pre>           \/\/ OAuthWebSecurity.RegisterGoogleClient();<\/pre>\n<\/div>\n<p><strong>WebPages<\/strong><\/p>\n<ul>\n<li>In _AppStart.cshtml register the custom provider as follows<\/li>\n<\/ul>\n<p>&#160;<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"> OAuthWebSecurity.RegisterClient(<span class=\"kwrd\">new<\/span> MyApplication.GoogleCustomClient(),<span class=\"str\">&quot;Google&quot;<\/span>,<span class=\"kwrd\">null<\/span>);<\/pre>\n<pre>           \/\/ OAuthWebSecurity.RegisterGoogleClient();<\/pre>\n<\/div>\n<p>This post has been cross posted to <a title=\"http:\/\/blogs.msdn.com\/b\/pranav_rastogi\/archive\/2012\/08\/23\/plugging-custom-oauth-openid-providers.aspx\" href=\"http:\/\/blogs.msdn.com\/b\/pranav_rastogi\/archive\/2012\/08\/23\/plugging-custom-oauth-openid-providers.aspx\">http:\/\/blogs.msdn.com\/b\/pranav_rastogi\/archive\/2012\/08\/23\/plugging-custom-oauth-openid-providers.aspx<\/a><\/p>\n<p>Please do reach me via twitter (@rustd) for any questions<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous post, I wrote about how you can use the existing providers for Google, Facebook etc. and retrieve extra metadata about the authenticated users. Let\u2019s assume you wanted to change the way the providers request for information. Some examples of this could be You want to request more data about the user You [&hellip;]<\/p>\n","protected":false},"author":408,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197],"tags":[7406,7407],"class_list":["post-2264","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","tag-oauth","tag-openid"],"acf":[],"blog_post_summary":"<p>In the previous post, I wrote about how you can use the existing providers for Google, Facebook etc. and retrieve extra metadata about the authenticated users. Let\u2019s assume you wanted to change the way the providers request for information. Some examples of this could be You want to request more data about the user You [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/408"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=2264"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2264\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=2264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=2264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=2264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}