This guide provides a comprehensive walk-through to integrate OpenID Connect (OIDC) authentication with SRAM in a C# application. We will create a Blazor Server application using Visual Studio (which has a Blazor Server boiler template) and C#.
This guide provides a comprehensive walk-through to integrate OpenID Connect (OIDC) authentication with SRAM in a C# application. We will create a Blazor Server application using Visual Studio (which has a Blazor Server boiler template) and C#. By the end of the guide, you'll achieve the following:
Before diving into the integration process, ensure you have properly set up SRAM:
In the Solution Explorer, navigate to ‘Program.cs’. Insert the OIDC configuration code snippet after the ‘builder’
initialization and before the ‘app’ creation.
This configuration will set up OpenID Connect (OIDC) authentication for your application:
builder.Services
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddCookie(OpenIdConnectDefaults.AuthenticationScheme)
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://proxy.acc.sram.eduteams.org/";
options.ClientId = "Your-EntityId-Goes-Here";
options.ClientSecret = "Your-ClientSecret-Goes-Here";
options.CallbackPath = "/oidc_callback";
options.ResponseType = "code";
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("openid");
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
options.Events.OnRedirectToIdentityProvider = context =>
{
context.ProtocolMessage.RedirectUri = "https://localhost:7275/oidc_callback";
return Task.CompletedTask;
};
});
After inserting the code, your application will be configured to use OpenID Connect (OIDC) for authentication
through the SRAM provider. The configuration includes:
By implementing this configuration, your application will be able to securely authenticate users via SRAM, receive
user information, and ensure that communication between your app and SRAM is secure and trusted.
Note: Remember to replace ‘Your-EntityId-Goes-Here’ with the APP-ID obtained from your SRAM environment and ‘Your-ClientSecret-Goes-Here’ with your Client Secret. Also, the ‘RedirectUri’’ specified in the example above needs to match the callback url you have set in your SRAM application. It's crucial to store these values securely and avoid hardcoding them directly into your application's source code, especially for production environments.
Continue in the Program.cs file. After the app.UseRouting(); line, insert the following code:
app.UseAuthentication();
app.UseAuthorization();
Replace the content of ‘Login.cshtml’ with the following code:
@page
@model SRAM.OIDC.Blazor_server.Pages.LoginModel
@{
}
Create a new class in the Pages folder and name it Login.cshtml.cs and insert the following code:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace SRAM.OIDC.Blazor_server.Pages
{
public class LoginModel : PageModel
{
public async Task OnGet(string redirectUri)
{
await HttpContext.ChallengeAsync("oidc", new
AuthenticationProperties
{ RedirectUri = redirectUri });
}
}
}
Replace the content of ‘Callback.cshtml’ with:
@page "oidc_callback"
@model SRAM.OIDC.Blazor_server.Pages.CallbackModel
@{
}
Create a new class in the Pages folder and name it ‘Callback.cshtml.cs’ and add the following code:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace SRAM.OIDC.Blazor_server.Pages
{
public class CallbackModel : PageModel
{
public void OnGet()
{
}
}
}
The Login page serves as an entry point to start the OIDC authentication process, while the Callback page acts as a landing point after the user has been authenticated by the OIDC provider. It's important to structure these pages correctly, as they play crucial roles in the OIDC authentication flow.
@page "/"
@inject AuthenticationStateProvider AuthProvider
<PageTitle>Index</PageTitle>
<h1>SRAM Blazor application</h1>
<p>This app demonstrates how to connect to SRAM using OIDC.</p>
<AuthorizeView>
<Authorized>
<p>Welcome to your new app, @context.User.Identity?.Name!</p>
</Authorized>
<NotAuthorized>
<div>
<a href="login?redirectUri=/">Log in</a>
</div>
</NotAuthorized>
</AuthorizeView>
This page acts as the main landing page for your application and displays content depending on the user's authentication status. Users who aren't authenticated will be provided with a link to log in using our newly created OIDC authentication with SRAM.
Run your application.
These steps are not required for authentication but can be beneficial in your application.
Mapping Attributes from SRAM
SRAM has many attributes originating from the underlying research or educational institute. A comprehensive list can be found here. We can use the ones in the column OIDC claim. To access the groups defined in the collaboration, based on the table, we need the field eduperson_entitlement in the eduperson_entitlement scope. We can achieve this by modifying the OIDC configuration in Program.cs. Begin by requesting the scope, then map the returned field to a claim. Add the following code below where we specified the “openid” scope “name” claim:
options.Scope.Add("eduperson_entitlement");
options.ClaimActions.MapJsonKey(ClaimTypes.Role, "eduperson_entitlement");
You've already seen how to use AuthorizeView to adjust content on pages based on authentication status. An alternative is to hide the full code behind (for instance, in an API) or an entire page. In classes, use the [Authorize] attribute above a class or method. For razor pages and components, use @attribute [Authorize].
Beyond the foundational steps, you can also utilize role-based authentication. Simply add the attribute ‘[Authorize(Roles ="Admin")]’ above a class or method. The attribute's usage is well-documented by Microsoft. Given
that SRAM uses a lengthy naming convention, like 'urn:mace:surf.nl:sram:group:collaboration-name:sub- collaboration-name:app-admin', it's practical to define it as a Policy in Program.cs:
builder.Services.AddAuthorizationCore(options =>
{
options.AddPolicy("RequireAdminRole", policy =>
policy.RequireRole('urn:mace:surf.nl:sram:group:collaboration-name:sub-collaboration-name:app-
admin'));
});
Now, use the identifier RequireAdminRole in both AuthorizeView and Controller as follows:
<AuthorizeView Policy="RequireAdminRole"></AuthorizeView>
[Authorize(Policy ="RequireAdminRole")]
By following the above steps, you have successfully set up OIDC authentication in a Blazor web application using Visual Studio and C#. Always ensure the confidentiality of your Client ID (APP-ID) and especially your Client Secret to maintain the security of your application.
Note: The configuration provided here is just a guideline to help you understand the essential components of setting up OIDC authentication with SRAM. It's crucial to understand that this is an example, and you should tailor the configuration to match your application's specific requirements and security considerations.