Which Version of Microsoft Identity Web are you using ?
Note that to get help, you need to run the latest version.
0.1.2-preview
Where is the issue?
Other? - please describe;
Is this a new or existing app?
I'm attempting to upgrade an existing app that uses MicrosoftAccount API (i.e. AddMicrosoftAccount()). I've repro'd the issue in the sample 2-1-Call-MSGraph.
Repro
Add this code in ConfigureServices before AddSignIn():
services.ConfigureApplicationCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromHours(1);
// TODO: MAKE COOKIE EXPIRE BEFORE ACCESS TOKEN
options.Events = new CookieAuthenticationEvents
{
OnSigningIn = async (context) =>
{
var identity = context.Principal.Identity as ClaimsIdentity;
var userId = context.Principal.Claims.FirstOrDefault(claim => claim.Type == "preferred_username" || claim.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")?.Value;
}
};
});
services.AddSignIn(Configuration);
Expected behavior
The OnSigningIn delegate should be called when a user logs in..
Actual behavior
In this case, the delegate is never called. If I use AddCookie() (as with MicrosoftAccount API), an exception "Scheme already exists: Cookies" is thrown at startup.
Additional context/ Logs / Screenshots
dotnet.txt
@jennyf19 @pmaytak : here we'd want to chain the events as usual (keep the previous events, and call them before or after our own implementation.
@toddheckel I'm unable to repro this. Could you share all your code in ConfigureServices? Would like to see how you set up .AddMicrosoftAccount(...) Thank you.
I modified active-directory-aspnetcore-webapp-openidconnect-v2\2-WebApp-graph-user\2-1-Call-MSGraph\Startup.cs, which does not call AddMicrosoftAccount().
@toddheckel But you don't need to use AddMicrosoftAccount. MSA are supported directly by the Microsoft identity platform
just set the tenant to "common" and make sure the app registration allows for Work or school accounts and microsoft personal accounts.
@jennyf19 asked me how I setup .AddMicrosoftAccount() and I was pointing that the sample I used to repro the issue doesn't call that. The app registration I am using allows for Work or school accounts and personal accounts. I am able to log into the sample with my work account just fine, it just never calls the cookie callback. I am using a similar technique in my production service with MSAL just fine.
I am no longer calling AddMicrosoftAccount() in my service.
Thanks for the additional information @toddheckel. I think I misread the above info where you mention .AddMIcrosoftAccount(..) and thought you were adding it as well. Can you share the code in ConfigureServices? I did try the same sample with the code you provided above and was not able to repro.
Yes sorry I wasn't clear about that. Below is the complete function. The only other changes I have made are to appsettings.json to use my AAD info.
So you are seeing the callback get called?
```c#
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
// Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
options.HandleSameSiteCookieCompatibility();
});
services.AddOptions();
services.ConfigureApplicationCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromHours(1);
// TODO: MAKE COOKIE EXPIRE BEFORE ACCESS TOKEN
options.Events = new CookieAuthenticationEvents
{
OnSigningIn = async (context) =>
{
var identity = context.Principal.Identity as ClaimsIdentity;
var userId = context.Principal.Claims.FirstOrDefault(claim => claim.Type == "preferred_username" || claim.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")?.Value;
}
};
});
services.AddSignIn(Configuration);
// Token acquisition service based on MSAL.NET
// and chosen token cache implementation
services.AddWebAppCallsProtectedWebApi(Configuration, new string[] { Constants.ScopeUserRead })
.AddInMemoryTokenCaches();
/*
// or use a distributed Token Cache by adding
.AddDistributedTokenCaches();
// and then choose your implementation.
// See https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-2.2#distributed-memory-cache
// For instance the distributed in memory cache
services.AddDistributedMemoryCache()
// Or a Redis cache
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});
// Or even a SQL Server token cache
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString =
_config["DistCache_ConnectionString"];
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
*/
// Add Graph
services.AddGraphService(Configuration);
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
services.AddRazorPages();
}
```
@toddheckel Perhaps, can you try to replace
services.ConfigureApplicationCookie(options =>
with
services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme, options =>
Thanks @pmaytak that calls the event. Does @pmaytak's suggestion above work for you @toddheckel ?
Yes, it works! Thanks, I appreciate the support!
Thanks for the quick response @toddheckel