Constantly get invalid scope error after udating my identityserver4 - asp.net

I had identityProviderService working with my API and web app, then I updated i updated my dependecies(identityServer4) and that resulted constantly in the following error either I use code or I hybrid.
IdentityServer4 Error: Invalid_scope
I checked the log and the scope was fine but I can resolve why I keep getting this error! The details as follows:
My local Idp (Identityserver4) log and the main error =>
IdentityServer4.Hosting.IdentityServerMiddleware: Information:
Invoking IdentityServer endpoint:
IdentityServer4.Endpoints.AuthorizeEndpoint for /connect/authorize
IdentityServer4.Validation.DefaultResourceValidator: Error: Scope
Bd.Web.Api not found in store.
IdentityServer4.Endpoints.AuthorizeEndpoint: Error: Request validation
failed IdentityServer4.Endpoints.AuthorizeEndpoint: Information: {
"ClientId": "BdWebAppClientId", "ClientName": "Bd web Client
Application", "RedirectUri": "https://localhost:xxxxx/signin-oidc",
"AllowedRedirectUris": [
"https://localhost:44386/signin-oidc" ], "SubjectId": "anonymous", "ResponseType": "code", "ResponseMode": "form_post",
"GrantType": "authorization_code", "RequestedScopes": "openid
profile Bd.Web.Api", "State":
"CfDJ8Foioa24zShFmzIFmkTbGBTrbiiEwQYmHGMRUN7FwsfKMgY2-olWJA1XVlAkA0uCWIR6HhMdu2X1exzVKTNFTcAD456Z0r3es5ki377uBEJgjA9jmyQFWWzTZV6_7GEmIC39xUh_b_YAqXgtzO0olZ52beNFuxruk_NshL47NhwcaETCH2cy3XTvRN0NTxZHmxVWglo13iSE7RVpNghHc7pBW7jCv7cB2RldQnEvsJ4s56AdiICw9sdKEJ5mQNoXngshanycX4MmD3qaW0TX6knY43pAqMuPgEEVqd7BXKt_koQfiQuAP3pQNbsyOAb1jtoZ8egUHiKgXjofs8ci2i4",
"PromptMode": "", "Raw": {
"client_id": "BdWebAppClientId",
"redirect_uri": "https://localhost:xxxxx/signin-oidc",
"response_type": "code",
"scope": "openid profile Bd.Web.Api",
"response_mode": "form_post",
"nonce": "637284460180108591.ZjIxYjhlZGEtYjk0Mi00M2UxLWExNWItOGYzMjhjODEyMGQzZmU5NjZmZDAtOTQwYi00YTFlLWJlMWUtM2U3YzBhM2NmNjQ4",
"state": "CfDJ8Foioa24zShFmzIFmkTbGBTrbiiEwQYmHGMRUN7FwsfKMgY2-olWJA1XVlAkA0uCWIR6HhMdu2X1exzVKTNFTcAD456Z0r3es5ki377uBEJgjA9jmyQFWWzTZV6_7GEmIC39xUh_b_YAqXgtzO0olZ52beNFuxruk_NshL47NhwcaETCH2cy3XTvRN0NTxZHmxVWglo13iSE7RVpNghHc7pBW7jCv7cB2RldQnEvsJ4s56AdiICw9sdKEJ5mQNoXngshanycX4MmD3qaW0TX6knY43pAqMuPgEEVqd7BXKt_koQfiQuAP3pQNbsyOAb1jtoZ8egUHiKgXjofs8ci2i4",
"x-client-SKU": "ID_NETSTANDARD2_0",
"x-client-ver": "5.5.0.0" }
My config comprises of three classes User, Resources and Client as follows:
public class Users
{
public static List<TestUser> Get()
{
return new List<TestUser> {
new TestUser {
SubjectId = "5BE86359-073C-434B-AD2D-A3932222DABE",
Username = "scott",
Password = "password",
Claims = new List<Claim> {
new Claim(JwtClaimTypes.Email, "scott#scottbrady91.com"),
new Claim(JwtClaimTypes.Role, "admin")
}
}
};
}
}
public class Resources
{
public static IEnumerable<IdentityResource> Ids()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Address()
};
}
public static IEnumerable<ApiResource> Apis()
{
return new List<ApiResource>
{
new ApiResource("Bd.Web.Api", "Bd Web Api") {
Description = "BD API Access",
//UserClaims = new List<string> {"role"},
ApiSecrets = new List<Secret> {new Secret("secret".Sha256())}
}
};
}
}
public class Clients
{
public static IEnumerable<Client> Get()
{
return new List<Client> {
new Client {
ClientId = "BdWebAppClientId",
ClientName = "Bd web Client Application",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = false,
ClientSecrets = new List<Secret> {
new Secret("secret".Sha256())},
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Address,
"Bd.Web.Api"
},
RedirectUris = new List<string>{"https://localhost:44386/signin-oidc"},
PostLogoutRedirectUris = new List<string>{ "https://localhost:44386/sigout-callback-oidc" }
}
};
}
}
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddIdentityServer()
.AddInMemoryClients(Clients.Get())
.AddInMemoryIdentityResources(Resources.Ids())
.AddInMemoryApiResources(Resources.Apis())
.AddTestUsers(Users.Get())
.AddDeveloperSigningCredential();
}
// 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.UseRouting();
app.UseIdentityServer();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
//endpoints.MapGet("/", async context =>
//{
// await context.Response.WriteAsync("Hello World!");
//});
});
}
}
My web app startup as follows:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
}
public IConfiguration Configuration { get; }
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.None;
});
services.AddMvc(options => { options.EnableEndpointRouting = false; }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
services.AddHttpContextAccessor();
services.AddTransient<BearerTokenHandler>();
services.AddHttpClient("ApiClient", client =>
{
//client.BaseAddress = new Uri("https://bandapi.azurewebsites.net/api/");
client.BaseAddress = new Uri("https://localhost:44301/api/");
//client.BaseAddress = new Uri("https://192.168.1.25:44301/api/");
client.Timeout = new TimeSpan(0, 0, 30);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
}).AddHttpMessageHandler<BearerTokenHandler>();
services.AddHttpClient("IdpClient", client =>
{
client.BaseAddress = new Uri("https://localhost:xxxxx/");
client.Timeout = new TimeSpan(0, 0, 30);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
}).AddHttpMessageHandler<BearerTokenHandler>();
services.AddAuthentication(options =>
{
options.DefaultScheme = "BdWebAppCookies";
options.DefaultChallengeScheme = "oidc";
//options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
//options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie("BdWebAppCookies" /*CookieAuthenticationDefaults.AuthenticationScheme*/, options =>
{
options.AccessDeniedPath = "/Authentication/AccessDenied";
})
.AddOpenIdConnect("oidc" /*OpenIdConnectDefaults.AuthenticationScheme*/, options =>
{
options.Authority = "https://localhost:xxxx/";
//options.RequireHttpsMetadata = true;
options.ClientId = "BdWebAppClientId";
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("address");
options.Scope.Add("Bd.Web.Api");
options.ClientSecret = "secret";
options.ResponseType = "code";
options.UsePkce = false;
options.SignInScheme = "BdWebAppCookies";
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}

In IdentityServer4 4.x the handling of api scopes was changed. Now you need to define all available api scopes and provide them to the configuration.
The updated documentation shows how it's done. https://identityserver4.readthedocs.io/en/latest/topics/resources.html#scopes
public static IEnumerable<ApiScope> GetApiScopes()
{
return new List<ApiScope>
{
new ApiScope(name: "read", displayName: "Read your data."),
new ApiScope(name: "write", displayName: "Write your data."),
new ApiScope(name: "delete", displayName: "Delete your data.")
};
}
Then add the scopes to your IdentityServer configuration:
services.AddIdentityServer()
.AddInMemoryApiScopes(Config.GetApiScopes());
Furthermore you need to add the scopes to your already defined ApiResources as described here: https://identityserver4.readthedocs.io/en/latest/topics/resources.html#api-resources
public static readonly IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("invoices", "Invoice API")
{
Scopes = { "invoice.read", "invoice.pay", "manage" }
},
new ApiResource("customers", "Customer API")
{
Scopes = { "customer.read", "customer.contact", "manage" }
}
};
}

I was had the same problem after updating to .NET Core 3.1 and IndentityServer4 V4.0.0. Only way I could get it to work is to remove the scope parameter on the client API request, using Angular 9 with angular-oauth2-oidc V9.2.1
const header = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });
const params = new HttpParams()
.append('username', userName)
.append('password', password)
.append('client_id', this.clientId)
.append('grant_type', 'password');
this.oauthService.issuer = this.baseUrl;
return from(this.oauthService.loadDiscoveryDocument())
.pipe(mergeMap(() => {
return this.http.post(this.oauthService.tokenEndpoint, params, { headers: header });
}));
This is NOT the way to do this, if you remove the scope then none of the profile information will be returned.

Related

Something like AddScoped in autofac? How to fix slow response time

I converted my application from .NET 5 to .NET 6. In the old version the response from the api was very fast. But in the new version it is very slow. The record has only 2 objects. This is my code. Please help. Thank!
In .NET 5 EF core:
namespace AspNetCoreTemplate.IoC
{
public static class NativeInjectorConfig
{
public static void RegisterServices(this IServiceCollection services)
{
services.AddScoped<ISongService, SongService>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
}
}
}
In .Net 6 EF core:
public class CoreModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(GenericRepository<>)).As(typeof(IGenericRepository<>)).InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(Service<>)).As(typeof(IGenericService<>)).InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
var apiAssembly = Assembly.GetExecutingAssembly();
var repoAssembly = Assembly.GetAssembly(typeof(DatabaseContext));
var serviceAssembly = Assembly.GetAssembly(typeof(MapProfile));
builder.RegisterAssemblyTypes(apiAssembly, repoAssembly, serviceAssembly).Where(x => x.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(apiAssembly, repoAssembly, serviceAssembly).Where(x => x.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope();
}
}
My response:
Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers(options => options.Filters.Add(new ValidateFilterAttribute())).AddFluentValidation(x => x.RegisterValidatorsFromAssemblyContaining<UserLoginDtoValidator>());
builder.Services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = builder.Configuration["Jwt:Audience"],
ValidIssuer = builder.Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped(typeof(NotFoundIdFilter<>));
builder.Services.AddScoped(typeof(NotFoundUpdateFilter<>));
builder.Services.AddAutoMapper(typeof(MapProfile));
builder.Services.AddDbContext<DatabaseContext>(x =>
{
x.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"), option =>
{
option.MigrationsAssembly(Assembly.GetAssembly(typeof(DatabaseContext)).GetName().Name);
});
});
builder.Host.UseServiceProviderFactory
(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder => containerBuilder.RegisterModule(new CoreModule()));
var app = builder.Build();
Old repo: https://github.com/ThanhDeveloper/AspNetCoreWebApplicationTemplate/blob/faf8296e20/AspNetCoreTemplate/IoC/NativeInjectorConfig.cs
New repo: https://github.com/ThanhDeveloper/AspNetCoreWebApplicationTemplate

Not receiving token when custom header is used in swagger dotnet core api

I have a dotnet core 5 API with swagger enabled.
I have added authorization in swagger api and works fine token is sent with the request.
But i have a requirement in which i need to send header value along with the request, for that purpose i have created a class:
public class SwaggerHeaderFilter : IOperationFilter {
public void Apply(OpenApiOperation operation, OperationFilterContext context) {
if (operation.Parameters == null)
operation.Parameters = new List<OpenApiParameter>();
var scheme = new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearer" } };
operation.Security.Add(new OpenApiSecurityRequirement {
[scheme] = new List<string>()
});
operation.Parameters.Add(new OpenApiParameter {
Name = "channelId",
In = ParameterLocation.Header,
Required = false // set to false if this is optional
});
}
}
And in startup.cs file i have used it like this:
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo { Title = "API", Version = "v1" });
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
In = ParameterLocation.Header,
Description = "Please enter token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type=ReferenceType.SecurityScheme,
Id="Bearer"
}
},
new string[]{}
}
});
c.OperationFilter<SwaggerHeaderFilter>();
});
But the problem is when i add custom header i am not getting anything in token

How to read values from appsettings.json inside a class in .Net 6?

I want to access the values of the Configurations Variables in another class.
Here is the appsetting.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Configurations": {
"FirstVerificationValidationDurationMinutes": 2,
"ResendedVerificationValidationDurationMinutes": 2,
"JwtRegisterTokenValidationDurationMinutes": 30,
"JwtLoginTokenValidationDurationMinutes": 30
}
}
And Here I want to use JwtLoginTokenValidationDurationMinutes's value (which is declared inside appsettings.json as you can see ablove) inside the class below:
public async Task<UserCredentialDto> JwtAuthentication(UserCredentialViewModel userCredential)
{
var user = await _userService.LoginUser(userCredential);
if (user is null)
{
return new UserCredentialDto
{
Status = new StatusMaker().ErrorStatus(user.Status.Message)
};
}
//TODO
var _key = "This is for test";
var tokenHandler = new JwtSecurityTokenHandler();
var tokenKey = Encoding.ASCII.GetBytes(_key);
//var tokenValidationDuration = HERE I NEED THE VALUE //HOW TO ACCESS VALUES FROM appsettings.json?
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddMinutes(/*tokenValidationDuration*/),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(tokenKey),
SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return new UserCredentialDto
{
Token = tokenHandler.WriteToken(token)
};
}
}
So how can I access values from appsettings.json ?
I tried using Microsoft.Extensions.Configuration but it seems it doesn't exist in .Net 6.
var JwtLoginTokenValidationDurationMinutes = builder.Configuration.GetSection("Configurations:JwtLoginTokenValidationDurationMinutes").Value;

ASP.NET CORE 3.1 Custom Identity ASP.Net Issue

i am getting following error when posting data
The output of this request is
My Code in Controller and Startup class is as below
Startup Class
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IRoleDao, RoleDao>();
services.AddSingleton<IRoleDao, RoleDao>();
services.AddSingleton<IUserDao, UserDao>();
services.AddSingleton<IUserRoleDao, UserRoleDao>();
services.AddSingleton<IUserClaimsDao, UserClaimsDao>();
services.AddIdentity<AppUser, AppRole>().AddDefaultTokenProviders();
services.AddTransient<IUserStore<AppUser>, UserStore>();
services.AddTransient<IRoleStore<AppRole>, RoleStore>();
//services.AddScoped<IIdentityAccountService, AccountService>();
services.AddScoped<JwtTokenGenerator>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidAudience = Configuration["Jwt:ValidAudience"],
ValidIssuer = Configuration["Jwt:ValidIssuer"],
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
});
services.AddControllers(options =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddAuthorization(options =>
{
options.AddPolicy("DeleteClaimPolicy", policy => policy.RequireClaim("DeleteClaim"));
options.AddPolicy("AddClaimPolicy", policy => policy.RequireClaim("CreateClaim"));
});
}
// 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.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
ControllerClass
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly JwtTokenGenerator _jwtTokenGenerator;
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger, JwtTokenGenerator jwtTokenGenerator)
{
_logger = logger;
_jwtTokenGenerator = jwtTokenGenerator;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
[AllowAnonymous]
[HttpGet("login")]
[ProducesResponseType(typeof(Result), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(Result), StatusCodes.Status500InternalServerError)]
public string Login()
{
string token = _jwtTokenGenerator.CreateUserToken("Test");
return token;
}
[HttpPost("create")]
[Authorize(Policy = "AddClaimPolicy")]
[ProducesResponseType(typeof(Result), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(Result), StatusCodes.Status500InternalServerError)]
public string CreateClaim()
{
return "Created Claim";
}
[HttpDelete("delete")]
[Authorize(Policy = "DeleteClaimPolicy")]
[ProducesResponseType(typeof(Result), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(Result), StatusCodes.Status500InternalServerError)]
public string DeleteClaim()
{
return "Deleted Claim";
}
}
However the when i comment the following line of code in ConfigureServices Method of Startup class
services.AddIdentity<AppUser, AppRole>().AddDefaultTokenProviders();
services.AddTransient<IUserStore<AppUser>, UserStore>();
services.AddTransient<IRoleStore<AppRole>, RoleStore>();
I get the desired output
On Closer observation, A second request to login is been called.
Please note that i am using custom implementation
GET /Account/Login?ReturnUrl=%2Fweatherforecast%2Fcreate HTTP/1.1
Can someone please correct me if i am missing something.
The above is solved, just changed
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidAudience = Configuration["Jwt:ValidAudience"],
ValidIssuer = Configuration["Jwt:ValidIssuer"],
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
});
to
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidAudience = Configuration["Jwt:ValidAudience"],
ValidIssuer = Configuration["Jwt:ValidIssuer"],
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
});
The parameter x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
is required to avoid redirection to Login
**> GET /Account/Login?ReturnUrl=%2Fapi%2FLSPAccount%2Frole%2Fcreate HTTP/1.1
Host: localhost:9000
User-Agent: insomnia/6.6.2
Content-Type: application/json
Accept: /**

signalR 401 error ($.connection.hub.start())

i tried to connect to hub with signalR in my page:
$(function() {
var rateHubProxy = $.connection.rateHub;
//...
$.connection.hub.url = 'http://localhost:8081/signalr';
$.connection.hub.connectionSlow(function () {
console.log('We are currently experiencing difficulties with the connection.')
});
$.connection.hub.error(function (error) {
console.log('SignalR error: ' + error)
});
$.connection.hub.start()
.done(function(){ console.log('Now connected, connection ID=' + $.connection.hub.id); })
.fail(function(){ console.log('Could not Connect!'); });
});
but i have 401 in $.connection.hub.start(). RateHub have Authorize attribute.
startup config in my app:
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
CookieAuthenticationOptions cookieOptions = new CookieAuthenticationOptions()
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
CookieName = ".AuctionWebAuth",
AuthenticationMode = AuthenticationMode.Active
};
app.UseCookieAuthentication(cookieOptions);
app.MapSignalR(new HubConfiguration() {
EnableDetailedErrors = true,
EnableJSONP = true
});
GlobalHost.HubPipeline.RequireAuthentication();
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new SignalRUserIdProvider());
}
How do I get authorization?

Resources