ASP.NET MVC OAuth using OWIN
Almost five years after .NET Core was first released, .NET Framework is still widely used. Many companies have existing projects built using .NET Framework, and migration to .NET Core is not yet on their roadmap. Most DocuSign C# code examples are built using .NET Core as recommended by Microsoft.
This blog post discusses the implementation of OAuth Authorization Code Grant flow in ASP.NET Framework MVC applications with OWIN (Open Web Interface) and includes an extended code example based on DocuSign’s Visual Studio Extension.
This code example is set to use .NET Framework 4.7.2, because in order to implement OAuth2, you need to use .NET Framework version 4.6.2 or higher, as any earlier version does not support TLS 1.2 by default.
When creating a new project, Visual Studio provides an out-of-the-box OWIN-based Identity implementation that handles OAuth providers like Google, Twitter and Facebook. When creating a new ASP.NET project in Visual Studio with included user authentication, the project comes with AccountController and ManageController classes handling registration, activation password reset, and so on. However, to authenticate with DocuSign using OAuth, you need only the minimal implementation, which is in the OwinStartup.cs file.
To run the code example provided with this blog post, you need Visual Studio 2017 or 2019. To handle dependency injection, the code example uses Autofac (Inversion of Control container).
The first step after downloading the code is to configure the application and update the appSettings section of the Web.config. The code example is configured to be used in the DocuSign developer environment. In the production environment, AuthorizationEndpoint, TokenEndpoint, UserInformationEndpoint and LogoutEndpoint values should be updated to account.docusign.com.
<add key="ClientId" value="{INTEGRATION_KEY_AUTH_CODE}" />
<add key="SecretKey" value="{SECRET_KEY}" />
<add key="AuthorizationEndpoint" value="https://account-d.docusign.com/oauth/auth" />
<add key="TokenEndpoint" value="https://account-d.docusign.com/oauth/token" />
<add key="UserInformationEndpoint" value="https://account-d.docusign.com/oauth/userinfo" />
<add key="LogoutEndpoint" value="https://account-d.docusign.com/logout" />
<add key="AppUrl" value="your application url, for example https://localhost:44359 in case of local" />
<add key="CallbackPath" value="/ds/callback" />
<add key="RequiredAccount" value="" />
Add your ClientId (integration key) and your SecretKey from your developer account. See Building an eSignature Integration in the DocuSign Developer Center to learn more about how to set up a new DocuSign integration and to configure these settings.
The default URL for the application is https://localhost:44359. Therefore, the default redirect URI to be added to the integration key is https://localhost:44359/ds/callback. If your application starts with a different port than 44359, you will need to update it: right-click your project in Visual Studio, select Properties - Web, and then update the Project Url value and save.
The RequiredAccount (optional) setting provides the option to specify a particular account ID (in GUID format) during the envelope creation. This is very useful in cases where the user has membership in multiple company accounts. This is used by the GetUserInfo method in OwinStartup.cs. If RequiredAccount is left empty, the example will return a list of all user accounts.
Accounts list is sorted by default account which will show as selected in the sender accounts drop-down list in ExampleController’s class Index.cshtml view.
The OAuth Authorization Code Grant flow
All authentication work is done in the DocuSignAuthenticationHandler
and DSChallengeResult
class methods in OwinStartup.cs.
The OAuth request starts from the Login
action in the Controllers/DSController
class by creating a new instance of the DSChallengeResult
class. DSChallengeResult
inherits from HttpUnauthorizedResult
and uses ExecuteResult
to initiate a new Challenge. This results in 401 - Unauthorized, and it will be intercepted by OWIN’s ApplyResponseChallengeAsync
method.
ApplyResponseChallengeAsync
: This is the first method to be called within the OWIN pipeline and will redirect to the DocuSign Account server, https://account-d.docusign.com/oauth/auth, for users to authenticate.
InvokeAsync
: This method checks if this is the correct authentication callback from DocuSign. If successful it calls OWIN’s AuthenticateAsync method. AuthenticateAsync
returns the result of the authentication, which in turn, if not null, will call AuthenticationManager.SignIn.
AuthenticateCoreAsync
: If all previous calls were successful this method creates a new ClaimsIdentity.
At this point, the user is successfully authenticated with the DocuSign account server and is redirected back with an authorization code (authorization_code
). This method exchanges the authorization code for an access token using the helper method Authenticate
. After the access token is received, the authenticated user’s information is collected by the GetUserInfo method.
At this point the application has all the information needed to create a new ClaimsIdentity
.
After the user is authenticated and an Identity with all claims has been created, a new instance of the DocuSign C# eSignature SDK ApiClient
can be created and used to make API calls, for example CreateEnvelope
.
Logging out is handled by the Controllers/DSController Logout
action. First, the app calls AuthenticationManager.SignOut, which revokes any Identity claims for the user and deletes the application cookie. Then a second call to DocuSign revokes the user’s current authentication session.
Summary
Many companies continue to build and extend .NET Framework applications. This new ASP.NET Framework MVC code example demonstrates how to add DocuSign OAuth authentication to these types of applications. The code example uses OWIN and the ASP.NET Identity framework to implement the OAuth flow.