Hello,
Really cool sample first of all - it works quite well when I just clone and run it, and since I was looking to help automate some of my emailing it's exactly what I was looking for ๐
Your contributing section article link leads nowhere by the way, so sorry if this issue is not in the desired format.
I am having an issue with the login process, which is odd. I did the following:
I have a completely fresh .NET core application, created by selecting "Web" (not MVC, Razor Pages I think), including authentication.
I then initially added a Microsoft account, which worked fine for authentication and logs me in.
Then I looked at this sample, which runs great locally after creating an application id / secret in the portal, and it correctly links my full name from my account.
Wanting to port the sample logic to my app, I changed startup (see below, included outcommented microsoft account logic):
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public const string ObjectIdentifierType = "http://schemas.microsoft.com/identity/claims/objectidentifier";
public const string TenantIdType = "http://schemas.microsoft.com/identity/claims/tenantid";
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
//services.AddAuthentication().AddMicrosoftAccount(options =>
//{
// options.ClientId = Configuration["Authentication:Microsoft:ApplicationId"];
// options.ClientSecret = Configuration["Authentication:Microsoft:Password"];
//});
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie();
// This sample uses an in-memory cache for tokens and subscriptions. Production apps will typically use some method of persistent storage.
services.AddMemoryCache();
services.AddSession();
// Add application services.
//services.AddSingleton<IConfiguration>(Configuration);
services.AddSingleton<IGraphAuthProvider, GraphAuthProvider>();
services.AddTransient<IGraphSdkHelper, GraphSdkHelper>();
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/Account/Manage");
options.Conventions.AuthorizePage("/Account/Logout");
});
// Register no-op EmailSender used by account confirmation and password reset during development
// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=532713
services.AddSingleton<IEmailSender, EmailSender>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseSession();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}
}
I copied the AzureAD settings from my working sample, and changed the port to match the app, and copied the "helper" folder with all cs files, and the extensions files into the extensions folder, added the nuget packages required and run the application.
What happens is I go through the whole authentication flow, all the way up to registering external provider and then the application throws me back to the index page, without having authenticated.
Pointers to what I'm doing wrong, and how I can port your logic to an existing application? ๐