Trying to store a string in a session while waiting for confirmation from the front end, but on the next request (confirmation request) the session is completely empty.
Config
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedMemoryCache();
services.AddSession(options => {
options.Cookie.Name = ".SingleTouch.API.Session";
options.IdleTimeout = TimeSpan.FromMinutes(20);
options.Cookie.IsEssential = true;
options.Cookie.HttpOnly = true;
});
string allowedHosts = Configuration.GetValue<string>("AllowedHosts");
services.AddCors(options =>
{
options.AddPolicy(name: CorsAllowedUrls,
builder =>
{
builder.WithOrigins(allowedHosts)
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddControllersWithViews(options =>
options.Filters.Add(new ApiExceptionFilter()));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(CorsAllowedUrls);
app.UseAuthentication();
app.UseAuthorization();
app.UseCookiePolicy();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
}
And in one endpoint I have
_httpContextAccessor.HttpContext.Session.SetString("payEvent", "bro you good?");
and on the the following endpoint it retrieves it again
_httpContextAccessor.HttpContext.Session.GetString("payEvent");
but on retrieval, the session is empty. It's definitely being added initially because if you inspect or run GetString in the first request the value exists. Asp core 6 is in use.
The Session has scoped lifetime, i.e. for any request you always get a new session. This is nesessary as each request can be issued by a differing user. If you want to store information for specific users, you need to do this in a singleton service.
Related
I am trying to implement SSO Authentication in ASP.Net Core 3.1 and deploy in Pivot Cloud Foundry(PCF).
In local it's working fine but after deployment getting below error
An unhandled exception occurred while processing the request.
Exception: The oauth state was missing or invalid.
Unknown location
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()
HomeController.cs
#if !LOCALTEST
[Authorize]
#endif
public IActionResult Index()
{
string user = "";
if (User.Identity.IsAuthenticated)
{
user = User.Identity.Name;
}
else
{
// WindowsIdentity.GetCurrent
user = WindowsIdentity.GetCurrent().Name.Substring(WindowsIdentity.GetCurrent().Name.LastIndexOf(#"\") + 1);
}
TempData["user"] = user;
return View();
}
Manifest.yml
---
applications:
- name: ApplicationName
memory: 1G
stack: cflinuxfs3
buildpacks:
- dicf_dotnet_core_buildpack_2339_cflinuxfs3
instances: 2
disk_quota: 1G
env:
ASPNETCORE_ENVIRONMENT: Development
GRANT_TYPE: authorization_code
SSO_IDENTITY_PROVIDERS : XXX-sso
SSO_SCOPES : openid,roles,user_attributes
SSO_AUTO_APPROVED_SCOPES : openid,roles,user_attributes
SSO_USERINFO_URL : https://appsso.login.sr3.pcf.xxx.com/userinfo
services :
- serviceName
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSession();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMvc();
services.Configure<MyOptions>(myOptions =>
{
myOptions.ConnString = Configuration.GetConnectionString("DefaultConnection");
});
services
.AddMvc()
.AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
services.AddScoped<IRepository, RepositoryConcrete>();
services.AddControllersWithViews();
services.AddRazorPages();
services.AddCloudFoundryContainerIdentity(Configuration);
services.AddAuthentication((options) =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CloudFoundryDefaults.AuthenticationScheme;
})
.AddCookie((options) =>
{
options.AccessDeniedPath = new PathString("/Home/AccessDenied");
})
.AddCloudFoundryOAuth(Configuration);
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddControllersWithViews();
var serviceInfos = CloudFoundryServiceInfoCreator.Instance(Configuration);
var ssoInfo = serviceInfos.GetServiceInfos<SsoServiceInfo>().FirstOrDefault()
?? throw new NullReferenceException("Service info for an SSO Provider was not found!");
userInfoEndPoint = ssoInfo.AuthDomain + "/userinfo";
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedProto
});
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Please help me to know what i am missing or required modification.
Thanking in Advance!
Everything works fine and the session keeps it Session Id and data. Then I redirect a user to payment page. After successful payment the user is redirected back to my site
The problem is my sessions lost after redirecting to my application.
How can i fix it?
Thanks
//Redirection code
HttpContext.Response.Redirect(IyziGo.PaymentPageUrl,false);
//Main Configuration
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddRazorRuntimeCompilation();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromHours(4);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = new MyTransparentJsonNamingPolicy();
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
/*if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}*/
app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=startApp}");
endpoints.MapControllers();
});
}
PROBLEM: in localhost all method(GET,POST,PUT) working fine but after deployment in server i got CORS POLICY BLOCKED err. although in server GET method working fine
C# with ef core
following my Startup.cs file.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
readonly string AllowLocalHostOrigins = "_allowLocalHostOrigins";
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<venus_aestheticsContext>(options => options
// replace with your connection string
.UseMySql(Configuration["dbConnection:startup"],
mysqlOptions =>
{
mysqlOptions
.ServerVersion(new Version(8, 0, 18), ServerType.MySql);
}));
// services.AddScoped<IDataRepository<Token, long>, TokenManager>();
// services.AddMvc();
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});
services.AddControllers().AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddControllers();
// enable cors
services.AddCors(options =>
{
options.AddPolicy(AllowLocalHostOrigins,
builder =>
{
builder.WithOrigins("http://localhost:3000").AllowAnyHeader().AllowAnyMethod();
builder.WithOrigins("http://www.testing.com").AllowAnyHeader().AllowAnyMethod();
});
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
// services.AddPaging();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseOptions();
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
//c.RoutePrefix = string.Empty;
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseSession();
app.UseRouting();
app.UseCors(AllowLocalHostOrigins);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Can you please replace
app.UseCors(AllowLocalHostOrigins);
With
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
I am working on asp.net core signalr 1.1.0 under asp.net core 2.2 version. I want to
make the cross-domain request for web client and as well as a mobile client.
When I send request from javascript client, then this request blocked, and below error shows,
(index):1 Access to XMLHttpRequest at 'https://localhost:44373/chatHub/negotiate?token=12' from origin 'https://localhost:44381' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
My Javascript client code
var connection = new signalR.HubConnectionBuilder().withUrl("https://localhost:44373/chatHub?token="+12).build();
Signalr core service startup class code
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()/*WithOrigins("https://localhost:44381")*/
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
//services.AddCors();
}
// 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();
}
else
{
app.UseExceptionHandler("/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.UseHttpsRedirection();
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/chatHub");
});
//app.UseStaticFiles();
//app.UseCookiePolicy();
app.UseMvc();
}
builder.AllowAnyOrigin() its not working
builder => builder.WithOrigins("https://localhost:44381") its worked, but this is specific for this origin ,
I want to make AllowAnyOrigin()??
I got it working this way
On Configure services at the top
services.AddCors();
and in the Configure method
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services
.AddDbContext<ChatContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = 60000000;
});
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
services.AddMvcCore()
.AddAuthorization()
.AddJsonOptions(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
var identityServerAuthOptions = Configuration.GetSection("Identity").Get<IdentityServerAuthenticationOptions>();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = identityServerAuthOptions.Authority;
options.RequireHttpsMetadata = identityServerAuthOptions.RequireHttpsMetadata;
options.ApiName = identityServerAuthOptions.ApiName;
});
var settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.ContractResolver= new CamelCasePropertyNamesContractResolver();
services.AddSignalR()
.AddJsonProtocol(options => {
options.PayloadSerializerSettings = settings;
});
services.AddTransient<IUserService, UserService>();
services.AddCors();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
//Data.AddData(app.ApplicationServices.GetService<ChatContext>());
app.Use(async (context, next) =>
{
if (string.IsNullOrWhiteSpace(context.Request.Headers["Authorization"]))
{
if (context.Request.QueryString.HasValue)
{
var token = context.Request.QueryString.Value.Split('&').SingleOrDefault(x => x.Contains("authorization"))?.Split('=')[1];
if (!string.IsNullOrWhiteSpace(token))
{
context.Request.Headers.Add("Authorization", new[] { $"Bearer {token}" });
}
}
}
await next.Invoke();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseCors(x => x.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials());
app.UseSignalR(config =>
{
config.MapHub<UserHub>("/UsersHub");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
});
}
}
app.UseCors(builder =>
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
);
Whole code can be found here. This used to work just fine for me. I haven't opened it lately though
Github Repo
I see two issues with your code. Let's tackle them one by one.
Allowing all origins for the entire application even though you need it only for the SignalR connection. Consider the below code if you want to apply CORS policy only for the signalR endpoint
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<UsersHub>("/UsersHub")
.RequireCors((policyBuilder) => policyBuilder
.WithOrigins("clientUrls")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
});
It is recommended to not allow all origins but if you have such a use case then the below workaround can fix your problem. This is the trick of using .SetIsOriginAllowed(_ => true)
.SetIsOriginAllowed(_ => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
Further if you want more information, have a look at this guide for more details.
Below is my code from startup.cs,
public void ConfigureServices(IServiceCollection services){
services.AddMvc().AddJsonOptions(options =>{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
services.AddDistributedMemoryCache();
services.AddSession(options => {
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromSeconds(36000);
options.Cookie.HttpOnly = true;
});
services.AddCors(options => {
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env{
if (env.IsDevelopment()){
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
//app.UseCors("CorsPolicy");
// global cors policy
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseSession();
app.UseAuthentication();
app.UseMvc();
}
Below is the code to set and get userid in session:
HttpContext.Session.SetInt32("UserId", user.Id);
int userId = (int)HttpContext.Session.GetInt32("UserId");
I am getting below exception while reading session in a different action from the action where it is set. Any reason why session is not working?
This solution works only for dotnetcore 2.1 or above. My solution was dotnetcore 2.0