C
C#8mo ago
TreF01L

JwtBearerAuthentication

Guys, I'm so damn tired. I can't figure out why my code isn't working, been sitting with it for 12 hours now. I want to create a jwtBearerAuthentication and use it with SwaggerGen(). However, I don't get a header with the Bearer token in the request when I use Swagger (no errors), and when I use Postman to validate this request, I get an authorization header, but the HttpContext.User.Claims will be null. There are no errors and that puts me in a quandary.
49 Replies
Keswiik
Keswiik8mo ago
$code
MODiX
MODiX8mo ago
To post C# code type the following: ```cs // code here ``` Get an example by typing $codegif in chat For longer snippets, use: https://paste.mod.gg/
TreF01L
TreF01LOP8mo ago
namespace MailBridgeSupport.API;

using System.Text;
using MailBridgeSupport.Application.Services;
using MailBridgeSupport.DataAccess.SqlServer;
using MailBridgeSupport.DataAccess.SqlServer.Entities;
using MailBridgeSupport.DataAccess.SqlServer.Repositories;
using MailBridgeSupport.Domain.Interfaces;
using MailBridgeSupport.Domain.Interfaces.Application;
using MailBridgeSupport.Domain.Interfaces.DataAccess;
using MailBridgeSupport.Domain.Interfaces.Infrastructure;
using MailBridgeSupport.Domain.Options;
using MailBridgeSupport.Infrastructure.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;

public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<JWTSecretOptions>(
builder.Configuration.GetSection(JWTSecretOptions.JWTSecret));
builder.Services.Configure<SmtpOptions>(
builder.Configuration.GetSection(SmtpOptions.Smtp));
builder.Services.Configure<ImapOptions>(
builder.Configuration.GetSection(ImapOptions.Imap));

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHttpContextAccessor();

builder.Services.AddAuthentication().AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetSection("JWTSecret:Secret").Value!)),
};
});

builder.Services.AddAuthorization();

builder.Services.AddDetection();




namespace MailBridgeSupport.API;

using System.Text;
using MailBridgeSupport.Application.Services;
using MailBridgeSupport.DataAccess.SqlServer;
using MailBridgeSupport.DataAccess.SqlServer.Entities;
using MailBridgeSupport.DataAccess.SqlServer.Repositories;
using MailBridgeSupport.Domain.Interfaces;
using MailBridgeSupport.Domain.Interfaces.Application;
using MailBridgeSupport.Domain.Interfaces.DataAccess;
using MailBridgeSupport.Domain.Interfaces.Infrastructure;
using MailBridgeSupport.Domain.Options;
using MailBridgeSupport.Infrastructure.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;

public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<JWTSecretOptions>(
builder.Configuration.GetSection(JWTSecretOptions.JWTSecret));
builder.Services.Configure<SmtpOptions>(
builder.Configuration.GetSection(SmtpOptions.Smtp));
builder.Services.Configure<ImapOptions>(
builder.Configuration.GetSection(ImapOptions.Imap));

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHttpContextAccessor();

builder.Services.AddAuthentication().AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetSection("JWTSecret:Secret").Value!)),
};
});

builder.Services.AddAuthorization();

builder.Services.AddDetection();




builder.Services.AddScoped<IImapService, ImapService>();
builder.Services.AddScoped<ISmtpService, SmtpService>();
builder.Services.AddScoped<ISentMessagesRepository, SentMessagesRepository>();
builder.Services.AddScoped<ISessionsRepository, SessionsRepository>();
builder.Services.AddScoped<IUsersRepository, UsersRepository>();
builder.Services.AddScoped<IClientMessagesService, ClientMessagesService>();
builder.Services.AddScoped<IModeratorsService, ModeratorsService>();
builder.Services.AddScoped<ISentMessagesService, SentMessagesService>();
builder.Services.AddScoped<ISystemAdminsService, SystemAdminsService>();

builder.Services
.AddIdentityCore<UserEntity>()
.AddRoles<IdentityRole<Guid>>()
.AddEntityFrameworkStores<MailBridgeSupportDbContext>();

builder.Services.AddAutoMapper(config =>
{
config.AddProfile<ApiMappingProfile>();
config.AddProfile<DataAccessMappingProfile>();
});

builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});

options.OperationFilter<SecurityRequirementsOperationFilter>();
});


builder.Services.AddScoped<IImapService, ImapService>();
builder.Services.AddScoped<ISmtpService, SmtpService>();
builder.Services.AddScoped<ISentMessagesRepository, SentMessagesRepository>();
builder.Services.AddScoped<ISessionsRepository, SessionsRepository>();
builder.Services.AddScoped<IUsersRepository, UsersRepository>();
builder.Services.AddScoped<IClientMessagesService, ClientMessagesService>();
builder.Services.AddScoped<IModeratorsService, ModeratorsService>();
builder.Services.AddScoped<ISentMessagesService, SentMessagesService>();
builder.Services.AddScoped<ISystemAdminsService, SystemAdminsService>();

builder.Services
.AddIdentityCore<UserEntity>()
.AddRoles<IdentityRole<Guid>>()
.AddEntityFrameworkStores<MailBridgeSupportDbContext>();

builder.Services.AddAutoMapper(config =>
{
config.AddProfile<ApiMappingProfile>();
config.AddProfile<DataAccessMappingProfile>();
});

builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});

options.OperationFilter<SecurityRequirementsOperationFilter>();
});


builder.Services.AddCors(options =>
{
options.AddPolicy("Any", corsPolicyBuilder =>
{
corsPolicyBuilder
.WithOrigins(new[] { "http://localhost:5173", "https://localhost:5173", "http://localhost:5174" })
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});

builder.Services.AddDbContext<MailBridgeSupportDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("MailBridgeSupportDbContext"),
x => x.MigrationsAssembly("MailBridgeSupport.DataAccess.SqlServer")));

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}


app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.UseCors("Any");

app.MapControllers();

app.Run();
}
}
builder.Services.AddCors(options =>
{
options.AddPolicy("Any", corsPolicyBuilder =>
{
corsPolicyBuilder
.WithOrigins(new[] { "http://localhost:5173", "https://localhost:5173", "http://localhost:5174" })
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});

builder.Services.AddDbContext<MailBridgeSupportDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("MailBridgeSupportDbContext"),
x => x.MigrationsAssembly("MailBridgeSupport.DataAccess.SqlServer")));

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}


app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.UseCors("Any");

app.MapControllers();

app.Run();
}
}
.
Keswiik
Keswiik8mo ago
You may need to configure your authentication something like
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
TreF01L
TreF01LOP8mo ago
No description
TreF01L
TreF01LOP8mo ago
It's not going to work?
Keswiik
Keswiik8mo ago
what?
TreF01L
TreF01LOP8mo ago
I added service with Authentication here with using JwtBearer
Keswiik
Keswiik8mo ago
and that isn't doing what the snippet I linked shows
TreF01L
TreF01LOP8mo ago
No description
TreF01L
TreF01LOP8mo ago
something like that?
Keswiik
Keswiik8mo ago
give it a try and see what happens
TreF01L
TreF01LOP8mo ago
Bearer header exists but HttpContext.User.Claims is null
No description
Keswiik
Keswiik8mo ago
Well, how are you generating your tokens?
TreF01L
TreF01LOP8mo ago
public static string CreateAccessToken(UserInformation information, JWTSecretOptions options)
{
var accsessToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.ExpirationTime(DateTimeOffset.UtcNow.AddMinutes(10).ToUnixTimeSeconds())
.AddClaim(ClaimTypes.Name, information.Nickname)
.AddClaim(ClaimTypes.NameIdentifier, information.UserId)
.AddClaim(ClaimTypes.Role, information.Role)
.WithVerifySignature(true)
.Encode();

return accsessToken;
}

public static string CreateRefreshToken(UserInformation information, JWTSecretOptions options)
{
var refreshToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.ExpirationTime(DateTimeOffset.UtcNow.AddMonths(1).ToUnixTimeSeconds())
.AddClaim(ClaimTypes.Name, information.Nickname)
.AddClaim(ClaimTypes.NameIdentifier, information.UserId)
.AddClaim(ClaimTypes.Role, information.Role)
.WithVerifySignature(true)
.Encode();

return refreshToken;
}
public static string CreateAccessToken(UserInformation information, JWTSecretOptions options)
{
var accsessToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.ExpirationTime(DateTimeOffset.UtcNow.AddMinutes(10).ToUnixTimeSeconds())
.AddClaim(ClaimTypes.Name, information.Nickname)
.AddClaim(ClaimTypes.NameIdentifier, information.UserId)
.AddClaim(ClaimTypes.Role, information.Role)
.WithVerifySignature(true)
.Encode();

return accsessToken;
}

public static string CreateRefreshToken(UserInformation information, JWTSecretOptions options)
{
var refreshToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.ExpirationTime(DateTimeOffset.UtcNow.AddMonths(1).ToUnixTimeSeconds())
.AddClaim(ClaimTypes.Name, information.Nickname)
.AddClaim(ClaimTypes.NameIdentifier, information.UserId)
.AddClaim(ClaimTypes.Role, information.Role)
.WithVerifySignature(true)
.Encode();

return refreshToken;
}
TreF01L
TreF01LOP8mo ago
No description
TreF01L
TreF01LOP8mo ago
I used User from IdentityUser with Guid maybe it influences in some way
No description
TreF01L
TreF01LOP8mo ago
what do you think about it?
Keswiik
Keswiik8mo ago
What is JwtBuilder from? Don't recognize it granted I could be using an older version of asp.net core
TreF01L
TreF01LOP8mo ago
I'm using .net 8 What do you mean? I've written JwtHelper to generate this jwtTokens
using System.Security.Claims;
using CSharpFunctionalExtensions;
using JWT.Algorithms;
using JWT.Builder;
using MailBridgeSupport.Domain.Options;

namespace MailBridgeSupport.API;

public class JwtHelper
{
public static string CreateAccessToken(UserInformation information, JWTSecretOptions options)
{
var accsessToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.ExpirationTime(DateTimeOffset.UtcNow.AddMinutes(10).ToUnixTimeSeconds())
.AddClaim(ClaimTypes.Name, information.Nickname)
.AddClaim(ClaimTypes.NameIdentifier, information.UserId)
.AddClaim(ClaimTypes.Role, information.Role)
.WithVerifySignature(true)
.Encode();

return accsessToken;
}

public static string CreateRefreshToken(UserInformation information, JWTSecretOptions options)
{
var refreshToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.ExpirationTime(DateTimeOffset.UtcNow.AddMonths(1).ToUnixTimeSeconds())
.AddClaim(ClaimTypes.Name, information.Nickname)
.AddClaim(ClaimTypes.NameIdentifier, information.UserId)
.AddClaim(ClaimTypes.Role, information.Role)
.WithVerifySignature(true)
.Encode();

return refreshToken;
}
using System.Security.Claims;
using CSharpFunctionalExtensions;
using JWT.Algorithms;
using JWT.Builder;
using MailBridgeSupport.Domain.Options;

namespace MailBridgeSupport.API;

public class JwtHelper
{
public static string CreateAccessToken(UserInformation information, JWTSecretOptions options)
{
var accsessToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.ExpirationTime(DateTimeOffset.UtcNow.AddMinutes(10).ToUnixTimeSeconds())
.AddClaim(ClaimTypes.Name, information.Nickname)
.AddClaim(ClaimTypes.NameIdentifier, information.UserId)
.AddClaim(ClaimTypes.Role, information.Role)
.WithVerifySignature(true)
.Encode();

return accsessToken;
}

public static string CreateRefreshToken(UserInformation information, JWTSecretOptions options)
{
var refreshToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.ExpirationTime(DateTimeOffset.UtcNow.AddMonths(1).ToUnixTimeSeconds())
.AddClaim(ClaimTypes.Name, information.Nickname)
.AddClaim(ClaimTypes.NameIdentifier, information.UserId)
.AddClaim(ClaimTypes.Role, information.Role)
.WithVerifySignature(true)
.Encode();

return refreshToken;
}
public static Result<UserInformation> GetPayloadFromJWTTokenV2(string token, JWTSecretOptions options)
{
var payload = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.MustVerifySignature()
.Decode<UserInformation>(token);

return payload;
}

public static IDictionary<string, object> GetPayloadFromJWTToken(string token, JWTSecretOptions options)
{
var payload = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.MustVerifySignature()
.Decode<IDictionary<string, object>>(token);

return payload;
}
public static Result<UserInformation> GetPayloadFromJWTTokenV2(string token, JWTSecretOptions options)
{
var payload = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.MustVerifySignature()
.Decode<UserInformation>(token);

return payload;
}

public static IDictionary<string, object> GetPayloadFromJWTToken(string token, JWTSecretOptions options)
{
var payload = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(options.Secret)
.MustVerifySignature()
.Decode<IDictionary<string, object>>(token);

return payload;
}
Keswiik
Keswiik8mo ago
Ah, I worked directly with JwtSecurityToken since it is part of identity (as far as I know) JwtBuilder looks to be from https://github.com/jwt-dotnet/jwt
Keswiik
Keswiik8mo ago
you should follow their documentation on using the library with asp
TreF01L
TreF01LOP8mo ago
but I've used it
No description
TreF01L
TreF01LOP8mo ago
JwtBuilder Or do you mean something else?
TreF01L
TreF01LOP8mo ago
GitHub
GitHub - jwt-dotnet/jwt: Jwt.Net, a JWT (JSON Web Token) implementa...
Jwt.Net, a JWT (JSON Web Token) implementation for .NET - jwt-dotnet/jwt
TreF01L
TreF01LOP8mo ago
No description
Keswiik
Keswiik8mo ago
probably the nuget package for the repo I linked
TreF01L
TreF01LOP8mo ago
yea, and I've already used it in my project. I wrote this code 1 day ago you can see it on this screenshot And it doesn't work It is very stange, because there no errors And I don't know how to debbug it
Keswiik
Keswiik8mo ago
Well, it doesn't look like you're using all of the configuration options required to make it work with ASP.net. Look at the readme and compare their ConfigureServices with yours.
TreF01L
TreF01LOP8mo ago
Do you mean that I should paste this code to my project? But there is no such commands even for AddJwt. I only have AddJwtBearer
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtAuthenticationDefaults.AuthenticationScheme;
})
.AddJwt(options =>
{
// secrets, required only for symmetric algorithms, such as HMACSHA256Algorithm
// options.Keys = new[] { "mySecret" };

// optionally; disable throwing an exception if JWT signature is invalid
// options.VerifySignature = false;
});
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtAuthenticationDefaults.AuthenticationScheme;
})
.AddJwt(options =>
{
// secrets, required only for symmetric algorithms, such as HMACSHA256Algorithm
// options.Keys = new[] { "mySecret" };

// optionally; disable throwing an exception if JWT signature is invalid
// options.VerifySignature = false;
});
Keswiik
Keswiik8mo ago
No description
Keswiik
Keswiik8mo ago
the readme tells you the other dependencies you need
TreF01L
TreF01LOP8mo ago
very interesting. I cannot install JWT.Extensions.DependencyInjection in case this error
No description
TreF01L
TreF01LOP8mo ago
but JWT.Extentions.AspNetCore I've installed
TreF01L
TreF01LOP8mo ago
the best funiest thing is that I should have same versions but I cannot make it because the smallest version is 6 альфа
No description
Keswiik
Keswiik8mo ago
just roll back to the latest released version?
TreF01L
TreF01LOP8mo ago
something like that?
No description
Keswiik
Keswiik8mo ago
Wouldn't know, never used their library before. Give it a try and see if it works.
TreF01L
TreF01LOP8mo ago
nothing changed))
Keswiik
Keswiik8mo ago
// the non-generic version AddJwt() requires registering an instance of IAlgorithmFactory manually could be part of your problem, you should really pay attention to what's in that readme
TreF01L
TreF01LOP8mo ago
okay can you show how did you use it?
Keswiik
Keswiik8mo ago
services.AddIdentity<User, IdentityRole>(options => {
options.User.RequireUniqueEmail = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireDigit = false;
options.Password.RequireUppercase = false;
})
.AddEntityFrameworkStores<MyDbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => {
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters() {
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("idkputtingsomethinghereforexample"))
};
options.Events = new JwtBearerEvents() {
OnAuthenticationFailed = MyJwtBearerEvents.OnAuthenticationFailed,
};
});
services.AddIdentity<User, IdentityRole>(options => {
options.User.RequireUniqueEmail = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireDigit = false;
options.Password.RequireUppercase = false;
})
.AddEntityFrameworkStores<MyDbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => {
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters() {
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("idkputtingsomethinghereforexample"))
};
options.Events = new JwtBearerEvents() {
OnAuthenticationFailed = MyJwtBearerEvents.OnAuthenticationFailed,
};
});
this is what I use to configure jwt in my application although I still have a user service that is responsible for generating the tokens
TreF01L
TreF01LOP8mo ago
can you show it too, please?
Keswiik
Keswiik8mo ago
var authClaims = new[] {
new Claim(JwtRegisteredClaimNames.Sub, userId),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};

var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("justhereforanexample"));
var token = new JwtSecurityToken(
expires: <your_expiration_goes_here>,
claims: authClaims,
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256));
var authClaims = new[] {
new Claim(JwtRegisteredClaimNames.Sub, userId),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};

var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("justhereforanexample"));
var token = new JwtSecurityToken(
expires: <your_expiration_goes_here>,
claims: authClaims,
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256));
TreF01L
TreF01LOP8mo ago
JWTBearer and JWT NuGenPackets work in my previous project, but still don't work in my project I'm working on now I thought that it does't work because I don't confirm email foreach user but I'd turned off this functions in configuration and it didn't work
TreF01L
TreF01LOP8mo ago
Maybe it's because I configured it wrong somehow.
No description
Keswiik
Keswiik8mo ago
https://stackoverflow.com/questions/55361533/addidentity-vs-addidentitycore Could be, but I've never used AddIdentityCore so I'm not sure what it's missing compared to just AddIdentity
Stack Overflow
AddIdentity vs AddIdentityCore
In ASP.NET Core, you can add various services for identification: AddDefaultIdentity, AddIdentity and AddIdentityCore. What's the difference between AddIdentity and AddIdentityCore?
blueberriesiftheywerecats
Is this endpoint for authorized only? If not, it ignores token validation and stuff I dont reallu remember exact function, but if your endpoint allows anonymous you have to call something HttpContext.Authenticate... to authorize and get your user info
Want results from more Discord servers?
Add your server