Web API
55 TopicsMacos dotnet wacth https not working.
Hello; I wanted to start Asp.net core Angular training. I am a Macos M1 user. I installed the necessary plugins with Vscode and created a webapi. But the api does not work with the dotnet watch command. It says the reason is https certificate problem. launchSettings.json : { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { "http": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, "applicationUrl": "http://localhost:5000;https://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } } applicationUrl also only works when it is http. In the error command: Microsoft.Extensions.Hosting.Internal.Host[11] Hosting failed to start System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date. To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'. There is a long error like this. I enter the following commands in the terminal, in order: 1- dotnet dev-certs https 2- dotnet dev-certs https --trust I approve the certificate. When I say 3-dotnet dev-certs https --check, I get the error: No valid certificate found. I found the localhost certificates in Keychain Access and selected the always trust option. But I couldn't find a solution. Also: dotnet dev-certs https --trust Trusting the HTTPS development certificate was requested. If the certificate is not already trusted we will run the following command: 'security add-trusted-cert -p basic -p ssl -k <<login-keychain>> <<certificate>>' This command might prompt you for your password to install the certificate on the keychain. There is an addition process like To undo these changes: 'security remove-trusted-cert <<certificate>>' I didn't know how to do it. Can you help me with this?83Views0likes0Comments.NET Web API CancellationToken don't work with Angular .unsuscribe()?
In Angular, I make API calls by subscribing to observables. When a user cancels a request, the application unsubscribes to the subscription which cancels the request (I can see this in the network tab of the Chrome browser). However, it does not trigger the endpoint and so the cancellation token param in our endpoint is of no use. Is there a way around this? I need the cancellation token to cancel all database request.139Views0likes2CommentsIssue with Authentication
If anyone can give me a clue as to where I am going wrong. I have slowly been upgrading my code base from .NET 6 to .NET 8. With my authorization controller, in the authorize method with .NET 6 this line of code var results = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme) would return null or not succeed.I would then hit the Login Razor Page and Sign In, the same result would then be an actual `AuthenticateResult`. With the upgrade to .NET 8, it always returns null even after I sign in. I have looked with the Dev Tools open and I can see that the sign in does generate a cookie. I am testing this from Postman using the authorization tab in there and using all the correct parameters. Here is what is not changed from .NET 6 to .NET 8: Authorize method: [HttpGet(Name = nameof(Authorize))] [HttpPost(Name = nameof(Authorize))] [IgnoreAntiforgeryToken] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task<IActionResult> Authorize() { var request = HttpContext.GetOpenIddictServerRequest() ?? throw new InvalidOperationException("The OpenID Connect request cannot be retrieved."); // Retrieve the user principal stored in the authentication cookie. // If it can't be extracted, redirect the user to the login page. var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme); if (result == null || !result.Succeeded) { if (request.HasPrompt(Prompts.None)) { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is not logged in." })); } return Challenge( authenticationSchemes: IdentityConstants.ApplicationScheme, properties: new AuthenticationProperties { RedirectUri = Request.PathBase + Request.Path + QueryString.Create( Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList()) }); } if (request.HasPrompt(Prompts.Login)) { var prompt = string.Join(" ", request.GetPrompts().Remove(Prompts.Login)); var parameters = Request.HasFormContentType ? Request.Form.Where(parameter => parameter.Key != Parameters.Prompt).ToList() : Request.Query.Where(parameter => parameter.Key != Parameters.Prompt).ToList(); parameters.Add(KeyValuePair.Create(Parameters.Prompt, new StringValues(prompt))); return Challenge( authenticationSchemes: IdentityConstants.ApplicationScheme, properties: new AuthenticationProperties { RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters) }); } if (request.MaxAge != null && result.Properties.IssuedUtc != null && DateTimeOffset.UtcNow - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value)) { if (request.HasPrompt(Prompts.None)) { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is not logged in." })); } return Challenge( authenticationSchemes: IdentityConstants.ApplicationScheme, properties: new AuthenticationProperties { RedirectUri = Request.PathBase + Request.Path + QueryString.Create( Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList()) }); } var user = await _userManager.GetUserAsync(result.Principal) ?? throw new InvalidOperationException("The user details cannot be retrieved"); var application = await _applicationManager.FindByClientIdAsync(request.ClientId) ?? throw new InvalidOperationException("Details concerning the calling client application cannot be found"); var permissionsArray = await _applicationManager.GetPermissionsAsync(application); var scopes = permissionsArray.Where(a => a.StartsWith("scp:")).Select(a => a[4..]).ToList().ToImmutableArray(); var authorizations = await _authorizationManager.FindAsync( subject: await _userManager.GetUserIdAsync(user), client: await _applicationManager.GetIdAsync(application), status: Statuses.Valid, type: AuthorizationTypes.Permanent, scopes: scopes).ToListAsync(); switch (await _applicationManager.GetConsentTypeAsync(application)) { case ConsentTypes.External when !authorizations.Any(): return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The logged in user is not allowed to access this client." })); case ConsentTypes.Implicit: case ConsentTypes.External when authorizations.Any(): case ConsentTypes.Explicit when authorizations.Any() && !request.HasPrompt(Prompts.Consent): var principal = await _signInManager.CreateUserPrincipalAsync(user); principal.SetScopes(scopes); principal.SetResources(await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync()); var authorization = authorizations.LastOrDefault(); if (authorization == null) { authorization = await _authorizationManager.CreateAsync( principal: principal, subject: await _userManager.GetUserIdAsync(user), client: await _applicationManager.GetIdAsync(application), type: AuthorizationTypes.Permanent, scopes: principal.GetScopes()); } principal.SetAuthorizationId(await _authorizationManager.GetIdAsync(authorization)); foreach (var claim in principal.Claims) { claim.SetDestinations(GetDestinations(claim, principal)); } return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); case ConsentTypes.Explicit when request.HasPrompt(Prompts.None): case ConsentTypes.Systematic when request.HasPrompt(Prompts.None): return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "Interactive user consent is required." })); default: return View(new AuthorizeViewModel { ApplicationName = await _applicationManager.GetDisplayNameAsync(application), Scope = string.Join(" ", scopes) }); } } Login page: [AllowAnonymous] public class LoginModel : PageModel { private readonly ApplicationUserManager _userManager; private readonly SignInManager<ApplicationUsers> _signInManager; private readonly ILogger<LoginModel> _logger; public LoginModel(SignInManager<ApplicationUsers> signInManager, ILogger<LoginModel> logger, ApplicationUserManager userManager) { _userManager = userManager; _signInManager = signInManager; _logger = logger; } [BindProperty] public InputModel Input { get; set; } public IList<AuthenticationScheme> ExternalLogins { get; set; } public string ReturnUrl { get; set; } [TempData] public string ErrorMessage { get; set; } public class InputModel { //Snipped fro brevity } public async Task OnGetAsync(string returnUrl = null) { if (!string.IsNullOrEmpty(ErrorMessage)) { ModelState.AddModelError(string.Empty, ErrorMessage); } returnUrl ??= Url.Content("~/"); // Clear the existing external cookie to ensure a clean login process await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); ReturnUrl = returnUrl; } public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl ??= Url.Content("~/"); if (ModelState.IsValid) { var user = await _userManager.FindByNameAsync(Input.Email); if (user != null) { if (!await _signInManager.CanSignInAsync(user) || (_userManager.SupportsUserLockout && await _userManager.IsLockedOutAsync(user))) { _logger.LogInformation("Login was unsuccessful through controller"); } if (!await _userManager.CheckPasswordAsync(user, Input.Password)) { _logger.LogInformation("Login was unsuccessful through controller"); await _userManager.AccessFailedAsync(user); } if (_userManager.SupportsUserLockout) { await _userManager.ResetAccessFailedCountAsync(user); } var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); if (result.Succeeded) { _logger.LogInformation("User logged in."); return LocalRedirect(returnUrl); } if (result.RequiresTwoFactor) { return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, Input.RememberMe }); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return RedirectToPage("./Lockout"); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } return Page(); } } Here is what I have changed in the .NET 6 to .NET 8 basically a move from `startup.cs` to `program.cs`: .NET 6 `startup.cs`: public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("Policy", builder => { builder.WithOrigins(Configuration.GetSection("Cors:Origins").GetChildren().Select(c => c.Value).ToArray()) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); services.AddControllers(); services.AddRazorPages(); services.AddDbContext<IdentDbContext>(options => { options.UseSqlServer( Configuration.GetConnectionString("IdentityDB")); options.UseOpenIddict(); }); services.AddDataProtection() .PersistKeysToDbContext<IdentDbContext>() .SetDefaultKeyLifetime(TimeSpan.FromDays(7)) .SetApplicationName("Applications"); services.AddIdentity<ApplicationUsers, ApplicationRoles>() .AddEntityFrameworkStores<IdentDbContext>() .AddUserStore<ApplicationUserStore>() .AddRoleStore<ApplicationRoleStore>() .AddRoleManager<ApplicationRoleManager>() .AddUserManager<ApplicationUserManager>() .AddErrorDescriber<ApplicationIdentityErrorDescriber>() .AddDefaultTokenProviders() .AddDefaultUI(); services.Configure<IdentityOptions>(options => { options.ClaimsIdentity.UserNameClaimType = Claims.Name; options.ClaimsIdentity.UserIdClaimType = Claims.Subject; options.ClaimsIdentity.RoleClaimType = Claims.Role; // Configure the options for the Identity Account options.SignIn.RequireConfirmedEmail = true; options.SignIn.RequireConfirmedAccount = true; options.User.RequireUniqueEmail = true; options.Lockout.MaxFailedAccessAttempts = 3; options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); }); services.Configure<SecurityStampValidatorOptions>(options => { options.ValidationInterval = TimeSpan.FromSeconds(1); }); services.AddQuartz(options => { options.UseMicrosoftDependencyInjectionJobFactory(); options.UseSimpleTypeLoader(); options.UseInMemoryStore(); }); services.AddQuartzHostedService(options => options.WaitForJobsToComplete = true); services.AddOpenIddict() // Register the OpenIddict core components. .AddCore(options => { options.UseEntityFrameworkCore() .UseDbContext<IdentDbContext>(); options.UseQuartz(); }) // Register the OpenIddict server components. .AddServer(options => { options.SetAuthorizationEndpointUris("/api/Authorization/Authorize") .SetTokenEndpointUris("/Token") .SetIntrospectionEndpointUris("/Introspect") .SetUserinfoEndpointUris("/api/Userinfo/Userinfo") .SetVerificationEndpointUris("/Verify"); options.RegisterScopes(Scopes.OpenId, Scopes.Email, Scopes.Profile, Scopes.Roles); options.UseReferenceAccessTokens() .UseReferenceRefreshTokens() .UseDataProtection(); options.AllowClientCredentialsFlow() .AllowAuthorizationCodeFlow() .RequireProofKeyForCodeExchange() .AllowRefreshTokenFlow(); if (_env.IsDevelopment()) { options.AddDevelopmentEncryptionCertificate() .AddDevelopmentSigningCertificate(); } else if (_env.IsProduction() || _env.IsStaging()) { options.AddSigningCertificate(Configuration.GetSection("CertifcateThumbprints:SigningCertificate").Value) .AddEncryptionCertificate(Configuration.GetSection("CertifcateThumbprints:EncryptionCertificate").Value); } options.UseAspNetCore() .EnableAuthorizationEndpointPassthrough() .EnableTokenEndpointPassthrough() .EnableStatusCodePagesIntegration() .EnableUserinfoEndpointPassthrough() .EnableVerificationEndpointPassthrough(); }) // Register the OpenIddict validation components. .AddValidation(options => { options.UseLocalServer(); options.UseDataProtection(); options.UseSystemNetHttp(); options.UseAspNetCore(); }); services.AddSwaggerGen(swagger => { swagger.OperationFilter<SwaggerDefaultValues>(); swagger.OperationFilter<AuthenticationRequirementOperationFilter>(); swagger.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); // Set the comments path for the Swagger JSON and UI. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); swagger.IncludeXmlComments(xmlPath); }); services.AddApiVersioning(); services.AddVersionedApiExplorer(options => { options.GroupNameFormat = "'v'VVVV"; options.DefaultApiVersion = ApiVersion.Parse("0.10.alpha"); options.AssumeDefaultVersionWhenUnspecified = true; }); services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>(); if (_env.IsDevelopment()) { services.AddHostedService<TestData>(); } else if (_env.IsStaging() || _env.IsProduction()) { services.AddHostedService<ProdStageSeed>(); } } public void Configure(IApplicationBuilder app, IApiVersionDescriptionProvider provider) { if (_env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseStatusCodePagesWithReExecute("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseCors("Policy"); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.DisplayOperationId(); var versionDescription = provider.ApiVersionDescriptions; foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(_ => _.ApiVersion)) { c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", $"API {description.GroupName}"); } }); app.UseSerilogRequestLogging(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllers(); }); } .NET 8 `program.cs`: builder.Services.AddCors(options => { options.AddPolicy("Policy", opt => { opt.WithOrigins(builder.Configuration.GetSection("Cors:Origins").GetChildren().Select(c => c.Value).ToArray()!) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); builder.Services.AddControllersWithViews() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new EntityIdJsonConverterFactory()); }); builder.Services.AddRazorPages(); builder.Services.AddDbContext<IdentDbContext>(options => { options.UseSqlServer( builder.Configuration.GetConnectionString("IdentityDB")); options.UseOpenIddict(); }); builder.Services.AddDataProtection() .PersistKeysToDbContext<IdentDbContext>() .SetDefaultKeyLifetime(TimeSpan.FromDays(7)) .SetApplicationName("Applications"); builder.Services.AddIdentity<ApplicationUsers, ApplicationRoles>() .AddEntityFrameworkStores<IdentDbContext>() .AddUserStore<ApplicationUserStore>() .AddRoleStore<ApplicationRoleStore>() .AddRoleManager<ApplicationRoleManager>() .AddUserManager<ApplicationUserManager>() .AddErrorDescriber<ApplicationIdentityErrorDescriber>() .AddDefaultTokenProviders() .AddDefaultUI(); builder.Services.Configure<IdentityOptions>(options => { options.ClaimsIdentity.UserNameClaimType = Claims.Name; options.ClaimsIdentity.UserIdClaimType = Claims.Subject; options.ClaimsIdentity.RoleClaimType = Claims.Role; options.SignIn.RequireConfirmedEmail = true; options.SignIn.RequireConfirmedAccount = true; options.User.RequireUniqueEmail = true; options.Lockout.MaxFailedAccessAttempts = 3; options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); }); builder.Services.Configure<SecurityStampValidatorOptions>(options => { options.ValidationInterval = TimeSpan.FromSeconds(1); }); builder.Services.AddQuartz(options => { options.UseSimpleTypeLoader(); options.UseInMemoryStore(); }); builder.Services.AddQuartzHostedService(options => options.WaitForJobsToComplete = true); builder.Services.AddOpenIddict() // Register the OpenIddict core components. .AddCore(options => { options.UseEntityFrameworkCore() .UseDbContext<IdentDbContext>(); options.UseQuartz(); }) // Register the OpenIddict server components. .AddServer(options => { options.SetAuthorizationEndpointUris("api/Authorization/Authorize") .SetTokenEndpointUris("Token") .SetIntrospectionEndpointUris("Introspect") .SetUserinfoEndpointUris("api/Userinfo/Userinfo") .SetVerificationEndpointUris("Verify"); options.RegisterScopes(Scopes.OpenId, Scopes.Email, Scopes.Profile, Scopes.Roles); options.UseReferenceAccessTokens() .UseReferenceRefreshTokens() .UseDataProtection(); options.AllowClientCredentialsFlow() .AllowAuthorizationCodeFlow() .RequireProofKeyForCodeExchange() .AllowRefreshTokenFlow(); if (builder.Environment.IsDevelopment()) { options.AddDevelopmentEncryptionCertificate() .AddDevelopmentSigningCertificate(); } else if (builder.Environment.IsProduction() || builder.Environment.IsStaging()) { options.AddSigningCertificate(builder.Configuration.GetSection("CertifcateThumbprints:SigningCertificate").Value!) .AddEncryptionCertificate(builder.Configuration.GetSection("CertifcateThumbprints:EncryptionCertificate").Value!); } options.UseAspNetCore() .EnableAuthorizationEndpointPassthrough() .EnableTokenEndpointPassthrough() .EnableStatusCodePagesIntegration() .EnableUserinfoEndpointPassthrough() .EnableVerificationEndpointPassthrough(); }) // Register the OpenIddict validation components. .AddValidation(options => { options.UseLocalServer(); options.UseDataProtection(); options.UseSystemNetHttp(); options.UseAspNetCore(); }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(swagger => { swagger.OperationFilter<SwaggerDefaultValues>(); swagger.OperationFilter<AuthenticationRequirementOperationFilter>(); swagger.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); // Set the comments path for the Swagger JSON and UI. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); swagger.IncludeXmlComments(xmlPath); }); builder.Services.AddApiVersioning(options => { options.DefaultApiVersion = new ApiVersion(0, 10, "alpha"); options.AssumeDefaultVersionWhenUnspecified = true; options.ReportApiVersions = true; }).AddMvc() .AddApiExplorer(options => { options.GroupNameFormat = "'v'VVVV"; options.SubstituteApiVersionInUrl = false; }); builder.Services.AddApplication() .AddInfrastructure(builder.Configuration) .AddDataLibrary(); builder.Services.AddHttpClient("Login", sp => { sp.BaseAddress = new Uri(builder.Configuration.GetSection("BaseAddresses:Api").Value!); }); builder.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>(); if (builder.Environment.IsDevelopment()) { builder.Services.AddHostedService<TestData>(); builder.Services.AddHostedService<ProdStageSeed>(); } else if (builder.Environment.IsStaging() || builder.Environment.IsProduction()) { builder.Services.AddHostedService<ProdStageSeed>(); } builder.Host.UseWolverine(opts => { opts.PersistMessagesWithSqlServer(builder.Configuration.GetConnectionString("IdentityDB")!); opts.UseEntityFrameworkCoreTransactions(); opts.Policies.AutoApplyTransactions(); opts.Policies.UseDurableLocalQueues(); opts.Discovery.IncludeAssembly(Assembly.Load("IdentityApplication")); opts.UseFluentValidation(); opts.Services.AddResourceSetupOnStartup(); opts.OnException<SqlException>().MoveToErrorQueue(); }); builder.Services.AddTransient<ExceptionMiddleware>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment() || app.Environment.IsStaging()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); var provider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>(); app.UseSwaggerUI(c => { c.DisplayOperationId(); var versionDescription = provider.ApiVersionDescriptions; foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(_ => _.ApiVersion)) { c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", $"API {description.GroupName}"); } }); } else { app.UseStatusCodePagesWithReExecute("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseCors("Policy"); app.UseSerilogRequestLogging(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseMiddleware<ExceptionMiddleware>(); app.MapRazorPages(); app.MapControllers(); app.Run(); So with the minimal change I made I cannot figure out why the result is always returning null. A cookie is generated by the Login Page and does show up in program and Postman. I understand that the AuthenticateAsync changed in .NET 7 but I cannot find any good documentation as to what might be affected in my code. Not sure what the cause is, but I have been stuck on this for over a coupe of weeks.133Views0likes0CommentsCustomer portal application using .NET, Microsoft 365 and Microsoft Graph
Hello, I want to develop an customer portal application using .NET, Microsoft 365 and Microsoft Graph. I want to retrieve information from SharePoint lists where there's the information I want to show customers (bookings, invoices, etc.). Customers don't have Microsoft 365 account so my idea is to use my credentials for retrieving the information from M365 and use Identity Framework for identify them filter queries. I am not sure this is possible, specially the fact of using my credentials for connecting to Microsoft 365. I really appreciate any suggestion or previous experience that you share. Thanks, Regards589Views0likes4CommentsDockerize App based .NET Framework 4.6.1
I have a Rest API based on .Net framework 4.6.1 I want to dockerize this API, but the problem is that I can't find a solution? All the solutions I found are almost all dedicated to other versions, for example, version 4.6.2, 4.7.0 etc. Can anyone recommend me the base image that I can use to build this application? I used mcr.microsoft.com/dotnet/framework/aspnet:4.8 but it is not suitable for my project.113Views0likes0CommentsHow to post using jquery to asp.net core api
I'm trying to develop a simple app to post to an api using jquery. I've tried multiple online suggestions and none of them work. I've even tried some of the AI code without success. I can get GET to reply back with data but POST is just not working. Going on my 3rd day on this. Please help. This is my api code: This is what I'm trying. Thanks for your time.232Views0likes1CommentDeploy an application that uses BackgroundService on IIS
As the title suggests, I have a webapi project deployed on IIS. The project has a simple timed background task that needs to be executed in the early hours of the day. I used BackgroundService to develop this functionality, I checked the execution logs and found that this background task was not executed correctly during this time, the strange thing is that it is always triggered correctly in the development environment. Later I realized that it should be related to the Idle Time-out of the IIS application pool. In the early hours of the morning, my site is not visited, so the site should be “hibernated”, so my background task can not be triggered correctly. I can only deploy the site using IIS, but I still need the background tasks, what should I do?250Views0likes0CommentsCombine Google Authentication & JWT Tokens using Cookie Authorization
* Edit: project is only a web-api, front-end will be developed in react(next.js) Hi guys! I'm a TypeScript Fullstack developer and I'm new to .NET and ASP.NET and basically this is one of my first projects using C# and .NET. My project's architecture requires a kind of different than out-of-the-box way of identifying users. I want Google Authentication which will create a local account (which I can relate other entities to) And JWT Tokens (access, refresh) generated and sent as cookies to the client and each protected endpoint to be using these cookies to authorize the requesting user. I haven't figured out a way of implementing this and still using mostly OOTB tools in order to keep modifications little as possible. Any tips and tricks on how to implement it? * Edit2: Just to be clear, I know how to create endpoints, and protected endpoints using the built in identity framework, using roles, etc... Its this combination of Google Auth, generating tokens, sending them to client as cookies basically is where my difficulty relies. * I have almost a blank new project, already set up with only google credentials347Views0likes3CommentsBlazor Web App Server Side .NET 8 .AddMicrosoftAccount not returning Azure App Roles
I have successfully created a Blazor Web App Server Side, and I am able to authenticate with Azure AD using the .AddMicrosoftAccount() builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() .AddMicrosoftAccount(config => { builder.Configuration.GetSection("Authentication:Microsoft").Bind(config); config.Events = new Microsoft.AspNetCore.Authentication.OAuth.OAuthEvents { OnCreatingTicket = async context => { var user = context.Principal; var claimIdentity = user.Identity as ClaimsIdentity; var rolesClaim = user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role); var role = user.IsInRole("Admin"); if (rolesClaim != null) { var claims = rolesClaim.Value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (var claim in claims) { claimIdentity.AddClaim(new Claim(ClaimTypes.Role, claim)); } } await Task.CompletedTask; } }; }); But it's not returning the roles claim with the attached roles for the user. The roles are setup correctly in Azure. I've searched high and low on the internet for something that would give me a clue as to where to go. I've tried using OpenId, and the roles get returned there, but I can't seem to use them in components. How do I get these roles using the .AddMicrosoftAccount() method?255Views0likes0CommentsCan I access User Secrets from a _Framework_ Web API project?
I'm targeting .NET Framework 4.8, mainly because I sometimes have to interact with Access databases and I assume I have a better chance of that working for framework than .NET Core. When deployed, I want this API to pick up any credentials it needs from environment variables but I would like to be able to test it locally, so I'm trying to find the best place to store the credentials without checking them in. I have read this and similar articles - user secrets seems like a reasonable solution, maybe there are better ones. https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-8.0&tabs=windows&source=docs The part about "Manage User Secrets" in Visual Studio seemed to work at least partially: it installed Microsoft.Configuration.ConfigurationBuilders.UserSecrets and added this to my Web.config: <configSections> <section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false" /> </configSections> <configBuilders> <builders> <add name="Secrets" userSecretsId="583724f7-d984-4688-84cd-cb8b28df5527" type="Microsoft.Configuration.ConfigurationBuilders.UserSecretsConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.UserSecrets, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </builders> </configBuilders> It loaded up a secrets.xml file and I can find examples of adding secrets to that. Where I'm stuck is how to access them from the code. I see .NET Core examples where they call AddUserSecrets<Program>() on their ConfigurationBuilder in their Config.cs but again mine is a framework app and I just have a WebApiConfig.cs with a Register(HttpConfiguration config). In there it accesses GlobalConfiguration. I just don't have the past experience to figure out what the analogous thing would be for framework. Thanks, -Jeff1.1KViews0likes2Comments