.NET Core 1.x native OpenID Connect example
.NET has OIDC support built into it and the following is a basic example of one way to utilise it to connect to OpenAthens Keystone. Other options are available.
It is assumed that user has knowledge of developing applications using ASP.net and this example is based off the asp.net Core Web Application template. (See: http://asp.net)
Goal in this example
Authenticate a user and display all the received claims on a page. In the real world you would read the claims and feed them into your authorisation / user-session management process.
Instructions
Add the OIDC dependencies
Update the dependencies part of your project (e.g. project.json, NuGet
) to include both:
Microsoft.AspNetCore.Authentication.Cookies
Microsoft.AspNetCore.Authentication.OpenIdConnect
Add the OIDC configuration to appsettings.json
Add the following into, for example, your appsettings.json
document or equivalent and update with the settings from the configuration tab of the application record in the publisher dashboard:
"OIDCSettings": {
"Authority": "https://connect.openathens.net",
"ClientId": "{clientId from the OIDC application record created in the publisher dashboard}",
"ClientSecret": "{clientSecret from the OIDC application created in the publisher dashboard}"
}
You will also need to create the class to return the configuration items e.g.:
public class OIDCSettings
{
public string Authority { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
}
Configure Startup.cs
to use OpenID Connect
Configure Startup.cs
to use OIDC. Update the ConfigureServices
method, e.g:
// Add authentication services
services.AddAuthentication(
options => options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
// Get the OIDC settings from appsettings.json
services.Configure<OIDCSettings>(Configuration.GetSection("OIDCSettings"));
Add IOptions<OIDCSettings> oidcSettings
to the Configure method parameters – e.g:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IOptions<OIDCSettings> oidcSettings)
Between the app.UseStaticFiles()
and app.UseMVC()
lines, add:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
var options = new OpenIdConnectOptions()
{
AuthenticationScheme = "oidc", // callback will be on /signin-oidc
Authority = oidcSettings.Value.Authority,
ClientId = oidcSettings.Value.ClientId,
ClientSecret = oidcSettings.Value.ClientSecret,
GetClaimsFromUserInfoEndpoint = true,
ResponseType = "code id_token"
};
options.Scope.Clear();
options.Scope.Add("openid");
app.UseOpenIdConnectAuthentication(options);
For additional settings that can be used you should refer to the Microsoft asp.net core documentation on the OpenIdConnectOptions class: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.openidconnectoptions?view=aspnetcore-1.1
Add in login and view claim to _Layout.cshtml
Add the following into _Layout.cshtml
which will display a Login link if a user session does not exist and will display a link to logout and view the returned claims if a user session does:
<ul class="nav navbar-nav navbar-right">
@if (User.Identity.IsAuthenticated)
{
<li><a asp-controller="Account" asp-action="Claims">Account Profile</a></li>
}
else
{
<li><a asp-controller="Account" asp-action="Login">Login</a></li>
}
</ul>
Create User portal pages
Create a new folder in Views called Account
Add a new MVC View page called Claims and paste in the following code which will display all claims that have been returned:
<div class="row">
<div class="col-md-12">
<h3>Claims associated with current User</h3>
<table class="table">
<thead>
<tr>
<th>
Claim
</th>
<th>
Value
</th>
</tr>
</thead>
<tbody>
@foreach (var claim in User.Claims)
{
<tr>
<td>@claim.Type</td>
<td>@claim.Value</td>
</tr>
}
</tbody>
</table>
</div>
</div>
Create a AccountController class and add the following:
public IActionResult Login(string returnUrl = "/")
{
return new ChallengeResult("oidc", new AuthenticationProperties() { RedirectUri = returnUrl });
}
[Authorize]
public IActionResult Claims()
{
return View();
}
Example of accessing the attributes
An example of accessing the claims returned is:
Name = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value,
EmailAddress = User.Claims.FirstOrDefault(c => c.Type == "email")?.Value,