0

I have an Angular application with an ASP.NET Core backed.

It uses Auth0 as identity server, which issues access tokens (JWTs) to the angular app.

The back end uses Microsoft.AspNetCore.Authentication.JwtBearer, and Authorize attributes on on web API controllers.

Now I want to add some controller actions to server up dynamically generated PDF files. These should only be accessible to authenticated users, and if they have appropriate claims in their access token.

These new endpoints will be accessed via browser link rather than AJAX requests, so I can't send the bearer token in a header (as far as I am aware).

Given the existing auth infrastructure I have in place, what's the easiest way to add security to these new controllers?

The PDFs will be accessed via html anchor elements (e.g. <a href="path/to/doc.pdf" target="_blank">PDF</a>) which are generated in angular component templates.

I could add the bearer token as a query parameter. The major downside I read about for this approach is that the tokens may be obtainable in server logs etc.

Maybe there is an alternative to download the PDF via AJAX request (in which case the existing use of bearer token in a header would apply), but I'm not sure of a good way to do that.

Ergwun
  • 12,579
  • 7
  • 56
  • 83
  • Web API and MVC are exactly one product in ASP.NET Core. You cannot "log into one but not the other", it is not ASP.NET 4.5. If you can call "Web API" actions you can call "MVC" actions because they are exactly the same. Stop thinking they are different products, **they are not** – Camilo Terevinto Feb 28 '18 at 11:42
  • @CamiloTerevinto Ok, MVC versus web API the wrong way to describe it, I'll edit the question. The key point is I need to authenticate the users differently for controller actions that are hit via browser request rather than AJAX request, since I can't send bearer token in header on browser requests. – Ergwun Feb 28 '18 at 11:48
  • https://stackoverflow.com/a/23797348/1851264 It will be probably the easiest way for you to use ajax request for saving file. There are a few alternatives, e.g. generating form in order to send POST request for pdf generation (that way you can include access_token in the request body). Also you can generate temporary link for downloading the file, link is generated via ajax with access_token, however file will be accessible for unauthenticated users via this link as long as link is "alive". – RavingDev Feb 28 '18 at 12:11
  • 1
    Claims are **not permissions**. [Identity vs Permissions](https://leastprivilege.com/2016/12/16/identity-vs-permissions/)!!! – Tseng Feb 28 '18 at 15:52
  • @CamiloTerevinto: Not true. In the past you could do that via middleware branching (`.UseMap` calls in the middleware pipeline configuration to selectively register the auth middlewares). In ASP.NET Core this was removed and just a single auth middleware call used. In ASP.NET Core you can do that with Authroize attribute and it's Scheme property. i.e. have cookie auth for mvc controllers and jwt bearer for WebAPI – Tseng Feb 28 '18 at 15:54
  • @Tseng What? There are **no** MVC controllers and there are **no** Web API controllers in ASP.NET Core. You can have multiple authorization methods, that doesn't mean they are different products or that they are different in any way – Camilo Terevinto Feb 28 '18 at 15:56
  • @CamiloTerevinto: technically they are the same, still semantically they are different (by routes and conventions) and you can very well have both "WebAPI-esque" and "MVC esque" controllers in an app. Same base class, different semantics and routings. And that being said, you can also have different auth mechanisms for them. on a side note, in ASP.NET Core 2.1 the `ApiController` base class is having a come back, though with a slightly different aim (changing default assumptions, like complex models being automatically [FromBody] and richer swagger metadata) – Tseng Feb 28 '18 at 21:07
  • @CamiloTerevinto: Also see https://blogs.msdn.microsoft.com/webdev/2018/02/27/asp-net-core-2-1-web-apis/. but it's unrelated to the argumentation, with Authorize Scheme property you can control (have Cookie for Mvc controllers (one returning views) and jwt/bearer for WebApi-esque controller (ones returning xml or json) – Tseng Feb 28 '18 at 21:09
  • @Tseng our claims are for roles. – Ergwun Mar 02 '18 at 01:23

1 Answers1

0

There's nothing wrong with adding the JWT to the href link. Either the JWT is encrypted, in which case they cannot see or tinker with it or it's signed in which case there shouldn't be any identifying info but a user still cannot tinker with it. I'd recommend abstracting out the name of the doc to use a number/guid rather than the actual file (you can always specify the correct name in the response). So you'd have;

<a href="https://yoursite.com/api/documents/1234-5435-1234.pdf?jwt=..." target="_blank">PDF</a>

Note: this assumes you're either encrypting the JWT or signing it - either is a requirement in this scenario. I wouldn't leave it plain text. Signing or encrypting effectively negates the need for auth provided a bit size large enough (2048+) public/private key pair is used, though if a user is logged in then their auth cookie still applies and gets sent regardless.

DiskJunky
  • 4,750
  • 3
  • 37
  • 66
  • But what about the points made here: https://stackoverflow.com/a/643480/177018 ? Even if it's encrypted, it could still be re-used. – Ergwun Mar 02 '18 at 01:25
  • @Ergwun, it can, that's why a correctly implemented JWT has an expiry to help prevent replay attacks – DiskJunky Mar 02 '18 at 01:36