OpenID Connect from ASP.NET Core with Visual Studio 2017
This article is out of date. Instead, please refer to the new documentation on connecting an ASP.NET Core 2.x application.
Adding OpenID Connect authentication to you ASP.NET Core web site is easy. In this example with Visual Studio 2017, it’s basically just a few clicks and a few lines of code and you will be up and running with Swedish BankID or some of the other e-ID’s out there.
The steps shown here creates a site from scratch, but the instructions may as well be applied to an existing application.
And hey, if you are on a Mac check this cool example of the same thing, but with no Windows involved!
Four steps are involved in getting going from zero:
- You’ve already got VS 2017 and ASP.Net Core set up on your computer. That was simple! Or you don’t and then you read this post from Microsoft to learn how.
- Create your basic ASP.NET Core application as a starting point
- Modify your application to defer authentication to Criipto Verify.
and to make it all work with the BankIDs you need to
- Set up an account with Criipto Verify to enable OpenID Connect on top of the national identities.
Create your basic ASP.NET Core web application
To create you new web site just create a new project in VS 2017 and choose the ASP.NET Core Web Application
Next you just pick Web Application with no authentiation.
Your web site is set up and you are ready to build and run this basic web site with nothing but an Ctrl-F5. Go ahead, give it a try!
Modify you ASP.NET Core app for OpenID Connect
So you’re up an running at you see something like this:
Nice starting point, but no authentication, so let’s add some plumbing to sign in users with Swedish BankID on their mobile phone.
Next up is adding the references to the OpenID Connect stuff. Open the NPM Package Manager Console to install the packages:
# Pull down the new packages
install-package Microsoft.AspNetCore.Authentication.Cookies
install-package Microsoft.AspNetCore.Authentication.OpenIdConnect
install-package Microsoft.AspNetCore.Authentication.JwtBearer
This will add the needed packages, and you may rebuild once the package restore process has completed.
Next we will add the initialization code to the Startup class (in Startup.cs
):
// Import the relevant namespaces at the top of the file
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
In the Configuration
method add these lines after the
app.UseStaticFiles();
line.
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true
});
var options = new OpenIdConnectOptions() {
AuthenticationScheme = "oidc", // callback will be on /signin-oidc
SignInScheme = "Cookies",
ResponseType = "code",
Authority = YOUR_DOMAIN, // For testing: "https://acme-corp.grean.id"
ClientId = YOUR_CLIENT_ID, // For testing: "urn:easyid:aspnet-core-demo"
ClientSecret = YOUR_CLIENT_SECRET // For testing: "0m4bGC+LO7QSBk7zf4d2Uhhlq48IRHbUC/D5yM4EROU="
};
// This may be modified to get the choice of authentication method from
// some other source, e.g. a dropdown in the UI
// Verify relies on this, but not needed for most OIDC identity proivders, such as Google, etc.
options.Events = new OpenIdConnectEvents() {
OnRedirectToIdentityProvider = context => {
context.ProtocolMessage.AcrValues = "urn:grn:authn:se:bankid:same-device";
return Task.FromResult(0);
}
};
// Wire in OIDC middelware
app.UseOpenIdConnectAuthentication(options);
The options
object sets the OpenID Connect middelware behaviour.
Specifically the AuthorizationScheme
property determines the callback you
must register with your OpenID Connect identity provider (see the
section at the end on how to do that for Criipto Verify).
In this case we set it to oidc
which means the callback will be on
/signin-oidc
. Still, this is handled by the middelware so no need for
any additional code.
For Criipto Verify, the Authority
, ClientID
, and ClientSecret
properties reference your
domain, client ID and client secret. If you’re in a hurry to try this out, you may go with
the values provided in the comments next to the properties.
Also note the AcrValues
(authentication context reference) parameter
in the OnRedirectToIdentityProvider
event handler. This is needed for Criipto Verify which supports several different
identity services on the same endpoint. If you use a simple OIDC identity
provider e.g. Google, you will not need this event handler.
For Criipto Verify the AcrValues
identifies the specific kind of authentication
you choose. Your options at the time of writing include:
- Norwegian BankID:
- Mobile:
urn:grn:authn:no:bankid:mobile
- Hardware token (kodebrikke):
urn:grn:authn:no:bankid:central
- Mobile:
- Swedish BankID:
- Same device:
urn:grn:authn:se:bankid:same-device
- Another device (aka mobile):
urn:grn:authn:se:bankid:another-device
- Same device:
- Danish NemID:
- Personal with code card:
urn:grn:authn:dk:nemid:poces
- Employee with code card:
urn:grn:authn:dk:nemid:moces
- Employee with code file:
urn:grn:authn:dk:nemid:moces:codefile
- Personal with code card:
We are now ready to authenticate. Before trying it out we just need a protected resource that will display user information.
The protected view: Start the login and show the user info
First add a login link to the front page. Put a login link in the menu,
or something to the same effect, in the _Layout.cshtml
shared view where the
top menu is rendered:
@if (Context.User.Identity.IsAuthenticated)
{
<li><a asp-area="" asp-controller="Home" asp-action="Logout">Logout</a></li>
}
else
{
<li><a asp-area="" asp-controller="Home" asp-action="Protected">Login</a></li>
}
To implement the Protected
view which will kick off the authentication process,
add a new action to the HomeController
. Notice the Authorize
attribute
which will start the OIDC flow.
// The Authorize attribute requires the user to be authenticated and will
// kick off the OIDC authentication flow
[Microsoft.AspNetCore.Authorization.Authorize]
public IActionResult Protected()
{
return View();
}
public async Task<IActionResult> Logout()
{
await HttpContext.Authentication.SignOutAsync("Cookies");
return View("Index");
}
Now, adding a simple view, Protected.cshtml
, in the Views/Home
to display the claims, and we are set.
@{
ViewData["Title"] = "ASP.NET Core + Criipto Verify";
}
<h2>Welcome @User.Claims.Where( c => c.Type == "name").FirstOrDefault().Value</h2>
<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
</dl>
Running the application
To execute an a login flow, remember to set the Authorization
, the ClientID
,
and the ClientSecret
. If you haven’t already set up a Criipto Verify account,
go to last section to do that. Or simply run with the test values
given in the comments in the code snippet further up.
One thing to remember: If you choose to just run with the test values for ClientId
etc.
do remember to set the port number of your web application to 50418
, as this value is already
registered with our test tenant in Criipto Verify.
Hit F5 and you’re off. Once the front page has opened up click the Login menu at the top.
That’s it!
Setting up your Criipto Verify account
As the various national and bank identity services do not support OpenID Connect or any other standard protocol, we use Criipto Verify as the identity service in the middle.
So, if you haven’t done so already, sign up for Criipto Verify: criipto.com/verify
A note on test users
In order to test the use of Norwegian BankID, Swedish BankID, and Danish NemID you need test identities.
For the sample shown above, we’ve set it up to use Swedish BankID (on the same device as your browser). As shown earlier you may easily switch to one of the other supported identities.
To obtain a test identity for Swedish BankID, go to https://demo.bankid.com and create the test¸identities you need. (Note that to install a test identity on your phone you will have to follow the guidelines on the site).
Also, please let us know if you need help getting your own test identities, and we will help you set them up. Just go to criipto.com/verify and sign up. Once signed up you can join our Slack channel from the Criipto Verify dashboard.
Setting up your Criipto Verify account
Name your first domain which will be a subdomain of grean.id. This will be the domain name we will use in the following.
Once signed up, go to the Applications tab to register your application.
Note that if you use Auth0 as your identity broker your life just got a little bit easier and you should take a look at our screencast showing how that scenario works.
But this post is not about that, so for this exercise just go for the manual option.
Remember to copy the Client ID value - you will need it when configuring the OpenID Connect middleware.
For the Callback URLs just enter the URL where your application may be reached for notification of the
authenticated user. In our example that would be http://localhost:<PORT NUMBER>/signin-oidc
.
The actual portnumber may be picked - or set - in the properties of you web site in Visual Studio.
If you use the test values provided in the code blocks, remember to set you application’s portnumber to 50418
.
Once the application has been registered in Criipto Verify, you have one more step to get it set up for OpenID Connect. Open the Criipto Verify application registration again and switch on the OAuth2 Code flow. This will generate a client secret that you will need in your application. Be sure to copy the value or you will have to generate a new one. (As with any other password we will, of course, only store the hashed value)
With this you will be able to set up your application to authenticate using any of the enabled identity services: Danish NemID, Swedish BankID and/or Norwegian BankID.
Go to criipto.com to sign up today to quickly enable your applications to accept real people’s real identities. We run a tight ship to ensure that you get the same level of security and safety that you get from the various proprietary bank and government solutions!
RECENT POSTS
June 15, 2017OpenID Connect from ASP.NET Core with Visual Studio 2017
March 24, 2017Sign text with BankID, NemID, right in your front-end
February 25, 2017OpenID Connect from ASP.NET Core - on Mac OSX
February 14, 2017Use BankID and NemID from a Node.js application
January 10, 2017Security considerations when building an identity service
December 15, 2016Real world identities online: Why and how?
December 07, 2016Criipto Verify connects Auth0 to Scandinavian national and bank identities
December 04, 2015Grean extends Auth0 with B2B onboarding and authorization
August 31, 2015Are security concerns holding back your B2B integration?