Update: everything has changed since I wrote this post in January : MSFT released its official OpenID middleware to connect the client, and I worked a lot with @manfredsteyer to adapt the OAuth2 authorization server built into Katana into OpenID connect. This combination provides a much easier and much more powerful solution that does not require any custom client code and is 100% compatible with standard OAuth2 / OpenID clients. The various steps that I mentioned in January can now be replaced with a few lines:
Server:
app.UseOpenIdConnectServer(options => { options.TokenEndpointPath = new PathString("/connect/token"); options.SigningCredentials.AddCertificate(certificate); options.Provider = new CustomOpenIdConnectServerProvider(); });
Client:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { Authority = "http://localhost:55985/", ClientId = "myClient", ClientSecret = "secret_secret_secret", RedirectUri = "http://localhost:56854/oidc" });
You can find all the details (and different samples) in the GitHub repository:
https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server
https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/dev/samples/Nancy
Josh, you are definitely on the right track, and your implementation of delegated / federated authentication seems pretty good (I assume you used the predefined OWIN middleware from Microsoft.Owin.Security.Facebook/Google/Twitter ).
What you need to do is create your own OAuth2 authorization server . You have many options to achieve this, but the simplest one is probably to connect OAuthAuthorizationServerMiddleware to your OWIN startup class. You will find it in the Microsoft.Owin.Security.OAuth Nuget package.
Although it would be best practice to create a separate project (often called an “AuthorizationServer”), I personally prefer to add it to my “API project” when it is not intended for use in multiple APIs (here you would insert it into the hosting project “api.prettypictures .com ").
In the Katana repository you will find a great sample:
https://katanaproject.codeplex.com/SourceControl/latest#tests/Katana.Sandbox.WebServer/Startup.cs
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions { AuthorizeEndpointPath = new PathString("/oauth2/authorize"), TokenEndpointPath = new PathString("/oauth2/token"), ApplicationCanDisplayErrors = true, AllowInsecureHttp = true, Provider = new OAuthAuthorizationServerProvider { OnValidateClientRedirectUri = ValidateClientRedirectUri, OnValidateClientAuthentication = ValidateClientAuthentication, OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials, }, AuthorizationCodeProvider = new AuthenticationTokenProvider { OnCreate = CreateAuthenticationCode, OnReceive = ReceiveAuthenticationCode, }, RefreshTokenProvider = new AuthenticationTokenProvider { OnCreate = CreateRefreshToken, OnReceive = ReceiveRefreshToken, } });
Feel free to browse the entire project to see how the authorization consent form was implemented using simple Razor files. If you prefer a higher-level structure such as ASP.NET MVC or NancyFX, create your own AuthorizationController and Authorize controller (make sure you accept GET and POST) and use Attribute Routing according to the AuthorizeEndpointPath parameter defined in your OAuth2 (ie [Route("oauth2/authorize")] in my example, where I changed AuthorizeEndpointPath to use oauth2/ as the base of the path).
Another thing you need to do is add the OAuth2 authorization client to your web application. Unfortunately, there is no general OAuth2 customer support in Katana, and you will have to create your own. I personally submitted a proposal to the Katan team, but was refused. But don't panic, it's pretty easy to do:
Copy the appropriate files from the Microsoft.Owin.Security.Google repository located there: https://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs
You will need GoogleOAuth2AuthenticationHandler , GoogleOAuth2AuthenticationMiddleware , GoogleOAuth2AuthenticationOptions , GoogleAuthenticationExtensions (you will need to remove the first 2 methods that correspond to the Google OpenID implementation), IGoogleOAuth2AuthenticationProvider , GoogleOAuth2ReturnEndpointContext , GoogleOAuth2AuthenticationProvider , GoogleOAuth2AuthenticatedContext , IGoogleOAuth2AuthenticationProvider , GoogleOAuth2ReturnEndpointContext , GoogleOAuth2AuthenticationProvider , GoogleOAuth2AuthenticatedContext Once you have inserted these files into your project by placing "webpics.com", rename them accordingly and change the URLs of the authorization and access tokens to GoogleOAuth2AuthenticationHandler to match the ones you defined on the OAuth2 authorization server .
Then add the Use method from your renamed / custom GoogleAuthenticationExtensions to your OWIN launcher class. I suggest using AuthenticationMode.Active so that your users are directly redirected to the OAuth2 API authorization endpoint. Therefore, you must suppress the "api.prettypictures.com/Account/ExternalLogins" roundtrip and allow the OAuth2 middleware to modify the 401 response to redirect clients to your API.
Good luck. And do not be shy if you need more information;)