I have an app that is written on the top of an old ASP.NET MVC 5 framework using C#
. I want to enable OpenIdConnect authentication to allow my users to authenticate using a private OpenId server.
I was able to add the OpenId external provider using Microsoft.Owin.Security.OpenIdConnect project. Here is how configured the OpenId authentication provider
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
{
Authority = "openid-server-domain.com",
RedeemCode = true,
SaveTokens = true,
ResponseType = "code",
ClientId = "***",
ClientSecret = "***",
RedirectUri = "https://localhost:55555/connect/redirect",
PostLogoutRedirectUri = "/disconnect/sign-out",
Scope = "openid profile email"
});
As you can see above, I am requesting access to the profile and email scopes which should give me info like username
, email
and some others. I want to add the data sent by the OpenId server as claims to the user.
Question How to persist additional claims and tokens from external providers in ASP.NET MVC 5?
I managed to get it to work by subscribing to the SecurityTokenValidated
event and call the userinfo
API on the server. I am not sure if this is the best approach.
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
{
Authority = "openid-server-domain.com",
RedeemCode = true,
SaveTokens = true,
ResponseType = "code",
ClientId = "***",
ClientSecret = "***",
RedirectUri = "https://localhost:55555/connect/redirect",
PostLogoutRedirectUri = "/disconnect/sign-out",
Scope = "openid profile email"
Notifications = new OpenIdConnectAuthenticationNotifications()
{
SecurityTokenValidated = async context =>
{
var id = context.AuthenticationTicket.Identity;
var client = new HttpClient()
{
BaseAddress = new Uri("openid-server-domain.com"),
};
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", context.ProtocolMessage.AccessToken);
var response = await client.GetAsync("connect/userinfo");
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
var info = JsonConvert.DeserializeObject<OpenIdUserInfo>(data);
if(!String.IsNullOrWhiteSpace(info.Name))
{
id.AddClaim(new Claim("name", info.Name));
}
}
context.AuthenticationTicket = new AuthenticationTicket(id, context.AuthenticationTicket.Properties);
}
}
});