From URL JWT token authentication & manually authorizing HttpContext in .Net core MVC

Ali Alp
2 min readJan 18, 2019

In a normal authentication with JWT the token will be in the “Auth header” of the request and the authentication will take place as explained here

But in case you need to authorize your requests with JWT token while the token is in the URL like this:

https://localhost:444/controller/action?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoie1widXNlcm5hbWVcIjpcInRlYWNoZXJAa28uY29tXCIsXCJwZWVyVXNlck5hbWVcIjpcInN0dWRlbnRAa28uY29tXCIsXCJwbGF0Zm9ybUlkXCI6MCxcInRlbmFudElkXCI6XCI4M0IwM0RCQi0xQTEyLTQwQ0YtQjZDRS0wNDQ2RTA5RDFBNjcjZGV2b3AuYWxpQGdtYWlsLmNvbVwiLFwicGVlckRpc3BsYXlOYW1lXCI6XCJUZWFjaGVyIDFcIixcImRpc3BsYXlOYW1lXCI6XCJzdHVkZW50IDFcIixcInJ0Y1VybFwiOlwiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQ0L3dlYnJ0Yy9jYWxsXCIsXCJzZXJ2aWNlVXJsXCI6XCJodHRwczovL1NlcnZpY2UvTG9nL2xvZ1wifSIsImV4cCI6MTU0NzgxNzcxMiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQ0IiwiYXVkIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQ0In0.DUzq0Im1nXLdGtZVI389NhuMXDe0YkGpZJTvOHytOoQ

things will get a bit tricky. so I decided to make a quick tutorial to explain how I managed to implement it.

In a Nutshell

so let’s get to it :) your ConfigureServices method will be something like this :

services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});

services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

and your Configure method:

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
app.UseHttpsRedirection();
}

app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMiddleware(typeof(AuthorizationMiddleware));
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});

the magic will happen in

app.UseMiddleware(typeof(AuthorizationMiddleware));

Let’s have look at AuthorizationMiddleware’s invoke method in detail:

public async Task InvokeAsync(HttpContext context)
{
//getting the token from the URL
var queryString = HttpUtility.ParseQueryString(context.Request.QueryString.Value);

//setting the validation parameters
//warning : these parameters should be same with the token's issuer parameters
var validationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,

ValidIssuer = _settings.Value.Jwt_valid_issuer,
ValidAudience = _settings.Value.Jwt_valid_audience,
IssuerSigningKey =
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_settings.Value.Jwt_issuer_key))
};

var validator = new JwtSecurityTokenHandler();

if (!validator.CanReadToken(queryString.Get("token")))
throw new UnauthorizedAccessException("token is not readable");
try
{
//trying to parse the token
var principal =
validator.ValidateToken(queryString.Get("token"), validationParameters, out var validatedToken);
if (principal.HasClaim(c => c.Type == ClaimTypes.UserData))
{
var userData = principal.Claims.First(c => c.Type == ClaimTypes.UserData).Value;

//setting AuthData to be used for later usages in other middlewares
//as well as the controller which is in the MVC middleware
context.Items["AuthData"] = JsonConvert.DeserializeObject<LoginModel>(userData);

//authorizing the http context
context.User.AddIdentity((ClaimsIdentity) principal.Identity);

//invoking the next middleware
await _next.Invoke(context);
}
}
catch (Exception e)
{
throw;
}
}

therefore if this Middleware reaches the

await _next.Invoke(context);

it means that the token is valid and the HttpContext is authorized plus we have added the parsed version of the token to the HttpContext

context.Items["AuthData"] = JsonConvert.DeserializeObject<LoginModel>(userData);

So you can implement your controller like you have used the default JwtBearer authentication:

[HttpGet,Authorize]
public IActionResult Action()
{
//retrieve the parsed token
var loginModel = HttpContext.Items["AuthData"] as LoginModel;
return View(loginModel?.Username);
}

Let me know if you had any questions & have fun coding :)

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Ali Alp
Ali Alp

Written by Ali Alp

“Take it easy” is nonsense , take it as hard as you can and don’t let it go :)

No responses yet

Write a response