mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-18 20:58:06 +00:00
Move auth into middleware (#3133)
Closes #2098. This cleans up the authentication a bit; after this change we have two stages in the middleware pipeline: - `AuthenticationMiddleware` reads the JWT token (it does not validate it, this is done by the Azure Functions service) and stores it in `FunctionContext.Items["ONEFUZZ_USER_INFO"]` - `AuthorizationMiddleware` checks the user info against the `[Authorize]` attribute to see if the user has the required permissions - Functions can read the user info from the `FunctionContext` if needed The authorize attribute can be `[Authorize(Allow.User)]` or `Allow.Agent` or `Allow.Admin`. The `Admin` case is new and allows this to be declaratively specified rather than being checked in code. We have several functions which could be changed to use this (e.g. Pool POST/DELETE/PATCH, Scaleset POST/DELETE/PATCH), but I have only changed one so far (JinjaToScriban). One of the benefits here is that this simplifies the test code a lot: we can set the desired user info directly onto our `(Test)FunctionContext` rather than having to supply a fake that pretends to parse the token from the HTTP request. This will also have benefits when running the service locally for testing purposes (refer to internal issue). The other benefit is the ability to programmatically read the required authentication for each function, which may help with Swagger generation.
This commit is contained in:
@ -26,26 +26,13 @@ public abstract class DownloadTestBase : FunctionTestBase {
|
||||
public DownloadTestBase(ITestOutputHelper output, IStorage storage)
|
||||
: base(output, storage) { }
|
||||
|
||||
[Fact]
|
||||
public async Async.Task Download_WithoutAuthorization_IsRejected() {
|
||||
var auth = new TestEndpointAuthorization(RequestType.NoAuthorization, Logger, Context);
|
||||
var func = new Download(auth, Context);
|
||||
|
||||
var result = await func.Run(TestHttpRequestData.Empty("GET"));
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, result.StatusCode);
|
||||
|
||||
var err = BodyAs<ProblemDetails>(result);
|
||||
Assert.Equal(ErrorCode.UNAUTHORIZED.ToString(), err.Title);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Async.Task Download_WithoutContainer_IsRejected() {
|
||||
var req = TestHttpRequestData.Empty("GET");
|
||||
var url = new UriBuilder(req.Url) { Query = "filename=xxx" }.Uri;
|
||||
req.SetUrl(url);
|
||||
|
||||
var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context);
|
||||
var func = new Download(auth, Context);
|
||||
var func = new Download(Context);
|
||||
var result = await func.Run(req);
|
||||
Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);
|
||||
|
||||
@ -59,8 +46,7 @@ public abstract class DownloadTestBase : FunctionTestBase {
|
||||
var url = new UriBuilder(req.Url) { Query = "container=xxx" }.Uri;
|
||||
req.SetUrl(url);
|
||||
|
||||
var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context);
|
||||
var func = new Download(auth, Context);
|
||||
var func = new Download(Context);
|
||||
|
||||
var result = await func.Run(req);
|
||||
Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);
|
||||
@ -81,8 +67,7 @@ public abstract class DownloadTestBase : FunctionTestBase {
|
||||
var url = new UriBuilder(req.Url) { Query = "container=xxx&filename=yyy" }.Uri;
|
||||
req.SetUrl(url);
|
||||
|
||||
var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context);
|
||||
var func = new Download(auth, Context);
|
||||
var func = new Download(Context);
|
||||
|
||||
var result = await func.Run(req);
|
||||
Assert.Equal(HttpStatusCode.Found, result.StatusCode);
|
||||
|
Reference in New Issue
Block a user