This is a very simple trick to make AspNet Identity work with OpenId Authentication. More of all both approach is completely separate to each other, there is no any connecting point.
I am using Microsoft.AspNetCore.Authentication.OpenIdConnect package to configure but it should work with any other.
Configuring under Startup.cs with IAppBuilder
Over here there are two most important items to make compatible with AspNet Identity.
AutomaticChallenge = false, it would restrict from redirecting to OpenId Connect when a user comes to the site so that they would have the option to log in through OpenIdConnect or AspNet Identity.
OnTicketReceived = OnTicketReceived This is a delegate through which we can allow users coming from OpenIdConnect to register in our system through AspNet Identity. This is triggered once the user is authorized and successfully return to our website.
Implementation under AspNet Identity for OnTicketReceived
The above delegate has a parameter to get System.Security.Claims.ClaimsPrincipal. So, a factory can be created to get data model for User.
To simplify we can create a function under UserManager to register user through Claims.
That is all we need. Now the implementation of OnTicketReceived is simple.
I am using Microsoft.AspNetCore.Authentication.OpenIdConnect package to configure but it should work with any other.
Configuring under Startup.cs with IAppBuilder
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme,
LoginPath = new PathString("/Account/Login"),
CookieName = "MyProjectName",
})
.UseIdentity()
.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = "<AzureAdClientId>",
Authority = String.Format("https://login.microsoftonline.com/{0}", "<AzureAdTenant>"),
ResponseType = OpenIdConnectResponseType.IdToken,
PostLogoutRedirectUri = "<my website url>",
AutomaticChallenge = false,
Events = new OpenIdConnectEvents
{
OnTicketReceived = OnTicketReceived,
//OnAuthenticationFailed = OnAuthenticationFailed,
//OnRemoteFailure = OnRemoteFailure
},
AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme
});
Over here there are two most important items to make compatible with AspNet Identity.
AutomaticChallenge = false, it would restrict from redirecting to OpenId Connect when a user comes to the site so that they would have the option to log in through OpenIdConnect or AspNet Identity.
OnTicketReceived = OnTicketReceived This is a delegate through which we can allow users coming from OpenIdConnect to register in our system through AspNet Identity. This is triggered once the user is authorized and successfully return to our website.
Implementation under AspNet Identity for OnTicketReceived
The above delegate has a parameter to get System.Security.Claims.ClaimsPrincipal. So, a factory can be created to get data model for User.
To simplify we can create a function under UserManager to register user through Claims.
public class MyProjectUserManager
: UserManager<User>
{
public async Task<IdentityResult> CreateAsync(ClaimsPrincipal claimsPrincipal)
{
if (principal == null || !principal.Claims.Any())
{
throw new ArgumentException(nameof(principal));
}
// TODO: Compose user based on need.
var user = new User
{
UserName = principal.FindFirst(c => c.Type == ClaimTypes.Name)?.Value,
Email = principal.FindFirst(c => c.Type == ClaimTypes.Email)?.Value,
};
return await CreateAsync(user);
}
}
That is all we need. Now the implementation of OnTicketReceived is simple.
private async Task OnTicketReceived(TicketReceivedContext ticketReceivedContext)
{
// TODO: Need to be registered in service collection and set ServiceProvider is
// property to get services. Which can done through services.BuildServiceProvider()
var userManager = ServiceProvider.GetService<MyProjectUserManager>();
await userManager.CreateAsync(ticketReceivedContext.Principal);
}
Comments
Post a Comment