.NET 5 Blazor Server OKTA Authentication showing HTTP Error 400 - asp.net-core

Using ASP.NET Core (.NET 5) Blazor Server with OKTA. OKTA log page has been prompted. I am getting below error messge on submitting OKTA uid/pwd
HTTP Error 400. The size of the request headers is too long.
My middleware is as like below, using an OpenId Connect.
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddOpenIdConnect(options =>
{
options.RemoteAuthenticationTimeout = TimeSpan.FromMinutes(30);
options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = configuration["Okta:Domain"] + "/oauth2/default";
options.RequireHttpsMetadata = true;
options.ClientId = configuration["Okta:ClientId"];
options.ClientSecret = configuration["Okta:ClientSecret"];
options.ResponseMode = OpenIdConnectResponseMode.FormPost;
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add("offline_access");
options.UseTokenLifetime = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.AccessDeniedPath = "/Public/AccessDenied";
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
// Describe how to map the user info we receive to user claims
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
options.ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name", "string");
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "given_name", "string");
options.ClaimActions.MapJsonKey("LastName", "lastname", "string");
options.ClaimActions.MapJsonKey("FirstName", "firstname", "string");
options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email", "string");
options.ClaimActions.MapJsonKey("Groups", "Groups", "string");
options.ClaimActions.MapJsonKey("membership_roles", "membership_roles", "string");
options.SaveTokens = true;
options.NonceCookie.SameSite = SameSiteMode.Unspecified;
options.CorrelationCookie.SameSite = SameSiteMode.Unspecified;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "groups",
RequireSignedTokens = true,
ValidateIssuer = false
};
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, displayName: $"EPDOne_{GlobalVariables.LocalEnv.EnvironmentName}",
options =>
{
options.Cookie.Name = $"EPDOne_{ GlobalVariables.LocalEnv.EnvironmentName}";
options.Cookie.HttpOnly = false;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.IsEssential = true;
options.Events = new CookieAuthenticationEvents
{
// this event is fired everytime the cookie has been validated by the cookie middleware,
// so basically during every authenticated request
// the decryption of the cookie has already happened so we have access to the user claims
// and cookie properties - expiration, etc..
OnValidatePrincipal = context =>
{
// since our cookie lifetime is based on the access token one,
// check if we're more than halfway of the cookie lifetime
var now = DateTimeOffset.UtcNow;
TimeSpan timeElapsed = now.Subtract(DateTime.Now.AddDays(1));
TimeSpan timeRemaining = now.Subtract(DateTime.Now.AddDays(2));
if (context is not null)
{
if (context.Properties is not null && context.Properties.IssuedUtc is not null)
{
timeElapsed = now.Subtract(context.Properties.IssuedUtc.Value);
}
else
{
context.ShouldRenew = true;
}
if (context.Properties is not null && context.Properties.ExpiresUtc is not null)
{
timeRemaining = context.Properties.ExpiresUtc.Value.Subtract(now);
}
else
{
context.ShouldRenew = true;
}
}
if (timeElapsed > timeRemaining || context?.ShouldRenew == true)
{
context.ShouldRenew = true;
var identity = (ClaimsIdentity)context?.Principal?.Identity;
if (identity is not null && identity.IsAuthenticated)
{
string CurrentBaseAddress = CurrentURL(context.HttpContext);
string returnUrl = "";
if (string.IsNullOrEmpty(CurrentBaseAddress) == false)
{
returnUrl = "?returnUrl=" + CurrentBaseAddress;
}
context.Response.Redirect(GlobalVariables.OKTACallBackURI + $"/refresh{returnUrl}");
}
}
return Task.CompletedTask;
}
};
});
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/");
//options.Conventions.AllowAnonymousToFolder("/Public");
}
);
As you can see above, I used OpenId in Startup.cs and application is prompting with OKTA credential dialog and after submitting uid/pwd, page behaves like in a loop and then shows the HTTP Error 400 message. Any clues here?

Philipp Grigoryev - Thanks for your time. I later noticed inside my .NET Core Startup.cs file below code.
app.UseAuthorization();
app.UseAuthorization();
The correct lines should be
app.UseAuthentication();
app.UseAuthorization();
So actually Authentication middleware itself not enabled and in hurry I was using 2 lines of enabling Authorization itself. After the mentioned correction, it works. Sorry to anyone who spent time on this. I am closing this query.

Related

User.Identity is not retrieved when JWT auth is enabled

I have first started with a cookie authentication and somehow after also enabling JWT it doesnt let me to retrieve the user by the User.Identity, object
and I found this article which suggested that you can enable both
https://weblog.west-wind.com/posts/2022/Mar/29/Combining-Bearer-Token-and-Cookie-Auth-in-ASPNET
this is my program cs on the Authentication config
builder.Services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = "JWT_OR_COOKIE"/*"Identity.Application"*/;
options.DefaultChallengeScheme = "JWT_OR_COOKIE";
})
.AddCookie("Cookies", options =>
{
options.LoginPath = "/identity/account/login";
options.ExpireTimeSpan = TimeSpan.FromDays(1);
})
.AddJwtBearer("Bearer",options =>
{
options.RequireHttpsMetadata = false;
options.Authority = "/Security/Token/Validate"; // TODO: Update URL
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience=builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["Jwt:Key"])),
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/ConnectionsHub")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
})
.AddPolicyScheme("JWT_OR_COOKIE", "JWT_OR_COOKIE", options =>
{
// runs on each request
options.ForwardDefaultSelector = context =>
{
string authorization = context.Request.Headers[HeaderNames.Authorization];
if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer "))
return "Bearer";
return "Cookies";
};
});
...
app.UseAuthentication();
app.UseAuthorization();

SignalR authentication with Blazor wasm Bearer Token

I authenticated to Signalr with Bearer token and signalr said Authentication was
successful.
But Signalr Hub Context.Identity.User.Name is null after authentication.
How can i access to authenticated user information in SignalR Hub for connectionid and user mapping.
My Startup.cs code for authentication.
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Authority = "https://security.minima.local";
options.Audience = "blazor_web_app_api";
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new
TokenValidationParameters()
{
ValidateAudience = false
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/notification")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
})
.AddIdentityServerJwt();
You need to tell the TokenValidator which claim is the name and role claim and you do that by setting:
.AddMyJwtBearer(opt =>
{
...
opt.TokenValidationParameters.RoleClaimType = "roles";
opt.TokenValidationParameters.NameClaimType = "name";

Auth0 + Swashbuckle .Net Core 2.2. Missing claims in jwt token when using SwaggerUI

I am making a ASP.Net Core WebApi which is authentication via Auth0. I am using Swagger and SwaggerUI and trying to authenticate from Swagger UI.
// Add authentication services
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("Auth0", options =>
{
// Set the authority to your Auth0 domain
options.Authority = $"https://{Configuration["Auth0:Authority"]}";
// Configure the Auth0 Client ID and Client Secret
options.ClientId = Configuration["Auth0:ClientId"];
options.ClientSecret = Configuration["Auth0:ClientSecret"];
// Set response type to code
options.ResponseType = "code";
// Configure the scope
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.SaveTokens = true;
// Set the callback path, so Auth0 will call back to http://localhost:3000/callback
// Also ensure that you have added the URL as an Allowed Callback URL in your Auth0 dashboard
options.CallbackPath = new PathString("/callback");
// Configure the Claims Issuer to be Auth0
options.ClaimsIssuer = "Auth0";
// Saves tokens to the AuthenticationProperties
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = context =>
{
context.ProtocolMessage.SetParameter("audience", #"https://predictor-dev.api");
return Task.FromResult(0);
},
// handle the logout redirection
OnRedirectToIdentityProviderForSignOut = (context) =>
{
var logoutUri = $"https://{Configuration["Auth0:Authority"]}/v2/logout?client_id={Configuration["Auth0:ClientId"]}";
var postLogoutUri = context.Properties.RedirectUri;
if (!string.IsNullOrEmpty(postLogoutUri))
{
if (postLogoutUri.StartsWith("/"))
{
// transform to absolute
var request = context.Request;
postLogoutUri = request.Scheme + "://" + request.Host + request.PathBase + postLogoutUri;
}
logoutUri += $"&returnTo={ Uri.EscapeDataString(postLogoutUri)}";
}
context.Response.Redirect(logoutUri);
context.HandleResponse();
return Task.CompletedTask;
}
};
})
.AddJwtBearer(options =>
{
options.Authority = Configuration["Auth0:Authority"];
options.Audience = Configuration["Auth0:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/roles"
};
options.ClaimsIssuer = "Auth0";
});
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder =>
{
builder
.WithOrigins(Configuration["FrontendBaseUrl"])
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "Predictor API", Version = "v1" });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
c.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = $"{Configuration["Auth0:Authority"]}authorize?audience={Configuration["Auth0:Audience"]}",
Scopes = new Dictionary<string, string>
{
{ "read:books", "Access read book operations" },
{ "write:books", "Access write book operations" }
}
});
c.OperationFilter<SecurityRequirementsOperationFilter>();
});
Here is the token which is returned after authentication via SwaggerUI:
{
"iss": "my iss",
"sub": "my sub",
"aud": "my aud",
"iat": 1556002815,
"exp": 1556010015,
"azp": "azp",
"scope": "read:books"
}
The problem here is that token doesn't have openid and profile information.
I don't have any custom rules in Auth0 that could limit my scopes (I removed them totally).I tried different options, but I could not get any additional claims.
Is there any configuration in Swagger that I am missing?
Thank you.
You have to pass "openid" and "profile" scopes to extend your token with openid and profile information

Reading JWT Token from API in ASP.NET Core

My setup: I've created and have running a WebAPI solution that performs the authentication of a username and password against a source (currently a db). This generates the JWT token and returns it to the requesting app (a ASP.NET Core 2.2 app).
Most solutions talk of securing the WebAPI exposed methods but my approach is to only do the authentication through WebAPI. The individual apps need to accept the token so they can determine authorization.
Now the question: what is the best approach to reading the token from the WebAPI (which I've done already), validating it, and then storing it for any/all controllers to know there is an authenticated user (via Authorize attribute) so long as the token is valid?
Debugging this more, it seems my token is not being added to the headers. I see this debug message:
Authorization failed for the request at filter 'Microsoft.AspNet.Mvc.Filters.AuthorizeFilter'
Code Update2 - code that gets the JWT:
var client = _httpClientFactory.CreateClient();
client.BaseAddress = new Uri(_configuration.GetSection("SecurityApi:Url").Value);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//login
Task<HttpResponseMessage> response = ValidateUserAsync(client, username, password);
Task<Core.Identity.TokenViewModel> tokenResult = response.Result.Content.ReadAsAsync<Core.Identity.TokenViewModel>();
if (!response.Result.IsSuccessStatusCode)
{
if (tokenResult != null && tokenResult.Result != null)
{
ModelState.AddModelError("", tokenResult.Result.ReasonPhrase);
}
else
{
ModelState.AddModelError("", AppStrings.InvalidLoginError);
}
return View();
}
JwtSecurityToken token = new JwtSecurityToken(tokenResult.Result.Token);
int userId;
if (int.TryParse(token.Claims.First(s => s.Type == JwtRegisteredClaimNames.NameId).Value, out userId))
{
//load app claims
Core.Identity.UserInfo userInfo = Core.Identity.UserLogin.GetUser(_identityCtx, userId);
Core.Identity.UserStore uStore = new Core.Identity.UserStore(_identityCtx);
IList<Claim> claims = uStore.GetClaimsAsync(userInfo, new System.Threading.CancellationToken(false)).Result;
claims.Add(new Claim(Core.Identity.PowerFleetClaims.PowerFleetBaseClaim, Core.Identity.PowerFleetClaims.BaseUri));
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, JwtBearerDefaults.AuthenticationScheme);
ClaimsPrincipal principal = new ClaimsPrincipal(claimsIdentity);
//complete
AuthenticationProperties authProperties = new AuthenticationProperties();
authProperties.ExpiresUtc = token.ValidTo;
authProperties.AllowRefresh = false;
authProperties.IsPersistent = true;
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(JwtBearerDefaults.AuthenticationScheme, tokenResult.Result.Token);
//var stuff = HttpContext.SignInAsync(JwtBearerDefaults.AuthenticationScheme, principal, authProperties);
}
else
{
ModelState.AddModelError("", AppStrings.InvalidLoginError);
return View();
}
return RedirectToAction("Index", "Home");
Startup:
private void ConfigureIdentityServices(IServiceCollection services)
{
services.ConfigureApplicationCookie(options => options.LoginPath = "/Login");
//authentication token
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddCookie(opt =>
{
opt.LoginPath = "/Login";
opt.LogoutPath = "/Login/Logoff";
opt.Cookie.Name = Configuration.GetSection("SecurityApi:CookieName").Value;
}).AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = true,
ValidAudience = Configuration.GetSection("SecurityApi:Issuer").Value,
ValidateIssuer = true,
ValidIssuer = Configuration.GetSection("SecurityApi:Issuer").Value,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("SecurityApi:Key").Value)),
ValidateLifetime = true
};
});
Core.Startup authStart = new Core.Startup(this.Configuration);
authStart.ConfigureAuthorizationServices(services);
}
Auth:
public void ConfigureAuthorizationServices(IServiceCollection services)
{
services.AddDbContext<Identity.IdentityContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SecurityConn")));
services.AddScoped<DbContext, Identity.IdentityContext>(f =>
{
return f.GetService<Identity.IdentityContext>();
});
services.AddIdentityCore<Identity.UserInfo>().AddEntityFrameworkStores<Identity.IdentityContext>().AddRoles<Identity.Role>();
services.AddTransient<IUserClaimStore<Core.Identity.UserInfo>, Core.Identity.UserStore>();
services.AddTransient<IUserRoleStore<Core.Identity.UserInfo>, Core.Identity.UserStore>();
services.AddTransient<IRoleStore<Core.Identity.Role>, Core.Identity.RoleStore>();
services.AddAuthorization(auth =>
{
auth.AddPolicy(JwtBearerDefaults.AuthenticationScheme, new AuthorizationPolicyBuilder().AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build());
auth.AddPolicy(PFBaseClaim, policy => policy.RequireClaim(Identity.PFClaims.BaseUri));
});
}
In the end, my approach was to use a secure cookie and a base claim to prove the user authenticated.
private void ConfigureAuthentication(IServiceCollection services)
{
services.ConfigureApplicationCookie(options => options.LoginPath = "/Login");
//authentication token
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(opt =>
{
opt.LoginPath = "/Login";
opt.AccessDeniedPath = "/Login";
opt.LogoutPath = "/Login/Logoff";
opt.Cookie.Name = Configuration.GetSection("SecurityApi:CookieName").Value;
}).AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = true,
ValidAudience = Configuration.GetSection("SecurityApi:Issuer").Value,
ValidateIssuer = true,
ValidIssuer = Configuration.GetSection("SecurityApi:Issuer").Value,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("SecurityApi:Key").Value)),
ValidateLifetime = true
};
});
}
And at login:
AuthenticationProperties authProperties = new AuthenticationProperties();
authProperties.ExpiresUtc = token.ValidTo;
authProperties.AllowRefresh = false;
authProperties.IsPersistent = true;
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userStore.CreateAsync(user).Result, authProperties);
return RedirectToAction("Index", "Home");

HttpContext.User null with authenticated user?

So I'm working on a .net core 2 project which where we want to create a basic platform which we can use for our future projects. For the login we use Identity. We have it all setup, the user can succesfully login and the cookie gets set. For some reason once we call HttpContext.User this results in a null. I'm pretty sure it does find an identity, yet this identity is empty. We have checked the cookie and it is perfectly fine, it has it's token. We did add token authentication, but that should not interfere with the cookie system when it sets the cookie.
Below is the Startup.cs
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<MyIdentityDbContext>(options => options
.UseSqlServer("Data Source=PATH;Initial Catalog=DB;Persist Security Info=True;User ID=ID;Password=*******"));
services.AddSingleton<IJwtFactory, JwtFactory>();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie();
services.AddIdentity<User, IdentityRole>(options =>
{
options.SignIn.RequireConfirmedEmail = true;
options.User.RequireUniqueEmail = false;
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
})
.AddEntityFrameworkStores<MyIdentityDbContext>()
.AddDefaultTokenProviders();
services.Configure<IISOptions>(options =>
{
options.ForwardClientCertificate = false;
});
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = _signingKey,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
cfg.TokenValidationParameters = tokenValidationParameters;
cfg.SaveToken = true;
});
services.Configure<IdentityOptions>(options =>
{
// Password settings
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
options.Password.RequiredUniqueChars = 6;
// Lockout settings
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings
options.User.RequireUniqueEmail = true;
});
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.LoginPath = "/Account/Login"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
options.LogoutPath = "/Account/Logout"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = true;
options.Cookie = new CookieBuilder
{
HttpOnly = true,
Name = "MyAuthToken",
Path = "/",
SameSite = SameSiteMode.Lax,
SecurePolicy = CookieSecurePolicy.SameAsRequest
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("Employee"));
options.AddPolicy("OwnerOnly", policy => policy.RequireClaim("Owner"));
options.AddPolicy("AdminOnly", policy => policy.RequireClaim("Admin"));
options.AddPolicy("ModeratorOnly", policy => policy.RequireClaim("Moderator"));
});
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
}
Here is the code used in the controller to get the user:
User _user = await _userManager.GetUserAsync(HttpContext.User);
And the code we use to login the user:
var result = await _signInManager.PasswordSignInAsync(model.Email,
model.Password, true, false);
You wrote AddAuthentication two times, once for Cookie and once for JWT and override the defaults.
only use AddAuthentication once and add Cookie and JWT to it.
services.AddAuthentication(options =>
{
// set schema here
})
.AddCookie(config =>
{
//config cookie
})
.AddJwtBearer(config =>
{
//config jwt
});
Now that you have two authentication scheme, you must select which one you want to authenticate your request with
[Authorize(CookieAuthenticationDefaults.AuthenticationScheme)]
or
[Authorize(JwtBearerDefaults.AuthenticationScheme)]
or even both
[Authorize($"{CookieAuthenticationDefaults.AuthenticationScheme},{JwtBearerDefaults.AuthenticationScheme}")]