Skip to main content
Skip table of contents

.NET Core 2.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:

CODE
Microsoft.AspNetCore.Authentication.Cookies
Microsoft.AspNetCore.Authentication.OpenIdConnect

Configure Startup.cs to use OpenID Connect

Configure Startup.cs to use OIDC. Update the ConfigureServices method, e.g:

CODE
services.AddAuthentication(options => {
 
               options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
 
            })
            .AddCookie()
            // Here "oidc" is the AuthenticationScheme
            .AddOpenIdConnect("oidc", options => {
 
                options.Authority = "https://connect.openathens.net";
                options.ClientId = "{ClientID}";
                options.ClientSecret = "{ClientSecret}";
                options.GetClaimsFromUserInfoEndpoint = true;
                options.ResponseType = "code id_token";
                options.Scope.Clear();
                options.Scope.Add("openid");
                options.ClaimActions.MapUniqueJsonKey("eduPersonTargetedID", "eduPersonTargetedID");
                options.ClaimActions.MapUniqueJsonKey("eduPersonScopedAffiliation", "eduPersonScopedAffiliation");
 
           //   If you plan to map extended attributes, such as username etc:
          options.ClaimActions.MapUniqueJsonKey("username", "username");
     
                options.CallbackPath = newPathString("/redirect");


            });

Between the app.UseStaticFiles() and app.UseMVC() lines, add:

CODE
            //app.UseAuthenticatoin(); Adds the OIDC middleware
            app.UseAuthentication();

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&viewFallbackFrom=aspnetcore-2.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:

CODE
                    <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:

CODE
<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:

CODE
   public class AccountController: Controller
   {
       public async Task Login(stringreturnUrl = "/")
       {
            // specifying the scheme here "oidc"
            await HttpContext.ChallengeAsync("oidc", newAuthenticationProperties() { RedirectUri = returnUrl });
 
       }
 
       [Authorize]
       public IActionResult Claims()
       {
            returnView();
       }
 
       public IActionResult AccessDenied()
       {
            returnView();
       }
    }

Example of accessing the attributes

An example of accessing the claims returned is:

CODE
Name = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value,
EmailAddress = User.Claims.FirstOrDefault(c => c.Type == "email")?.Value,
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.