Skip to content

Commit a1661db

Browse files
authored
Add delegate OpenApiHttpTriggerAuthorization to be more configurable (#476)
1 parent 5dfe8cc commit a1661db

File tree

19 files changed

+473
-139
lines changed

19 files changed

+473
-139
lines changed

docs/openapi-core.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ Suppose you want to customise the look and feels of the Swagger UI page. In this
261261
}
262262
```
263263

264+
264265
### Use CSS and JavaScript Files from CDN ###
265266

266267
Alternatively, you can use both CSS and JavaScript files from CDN, which is from the Internet.

docs/openapi-in-proc.md

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -47,36 +47,36 @@ namespace MyFunctionApp
4747
{
4848
/* ⬇️⬇️⬇️ Add this ⬇️⬇️⬇️ */
4949
builder.Services.AddSingleton<IOpenApiConfigurationOptions>(_ =>
50-
{
51-
var options = new OpenApiConfigurationOptions()
52-
{
53-
Info = new OpenApiInfo()
54-
{
55-
Version = "1.0.0",
56-
Title = "Swagger Petstore",
57-
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
58-
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
59-
Contact = new OpenApiContact()
60-
{
61-
Name = "Enquiry",
62-
Email = "[email protected]",
63-
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
64-
},
65-
License = new OpenApiLicense()
66-
{
67-
Name = "MIT",
68-
Url = new Uri("http://opensource.org/licenses/MIT"),
69-
}
70-
},
71-
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
72-
OpenApiVersion = OpenApiVersionType.V2,
73-
IncludeRequestingHostName = true,
74-
ForceHttps = false,
75-
ForceHttp = false,
76-
};
77-
78-
return options;
79-
});
50+
{
51+
var options = new OpenApiConfigurationOptions()
52+
{
53+
Info = new OpenApiInfo()
54+
{
55+
Version = "1.0.0",
56+
Title = "Swagger Petstore",
57+
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
58+
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
59+
Contact = new OpenApiContact()
60+
{
61+
Name = "Enquiry",
62+
Email = "[email protected]",
63+
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
64+
},
65+
License = new OpenApiLicense()
66+
{
67+
Name = "MIT",
68+
Url = new Uri("http://opensource.org/licenses/MIT"),
69+
}
70+
},
71+
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
72+
OpenApiVersion = OpenApiVersionType.V2,
73+
IncludeRequestingHostName = true,
74+
ForceHttps = false,
75+
ForceHttp = false,
76+
};
77+
78+
return options;
79+
});
8080
/* ⬆️⬆️⬆️ Add this ⬆️⬆️⬆️ */
8181
}
8282
}
@@ -96,7 +96,30 @@ namespace MyFunctionApp
9696
public override void Configure(IFunctionsHostBuilder builder)
9797
{
9898
/* ⬇️⬇️⬇️ Add this ⬇️⬇️⬇️ */
99-
builder.Services.AddSingleton<IOpenApiHttpTriggerAuthorization, MyOpenApiHttpTriggerAuthorization>();
99+
builder.Services.AddSingleton<IOpenApiHttpTriggerAuthorization>(_ =>
100+
{
101+
var auth = new OpenApiHttpTriggerAuthorization(async req =>
102+
{
103+
var result = default(OpenApiAuthorizationResult);
104+
105+
var authtoken = (string)req.Headers["Authorization"];
106+
if (authtoken.IsNullOrWhiteSpace())
107+
{
108+
result = new OpenApiAuthorizationResult()
109+
{
110+
StatusCode = HttpStatusCode.Unauthorized,
111+
ContentType = "text/plain",
112+
Payload = "Unauthorized",
113+
};
114+
115+
return await Task.FromResult(result).ConfigureAwait(false);
116+
}
117+
118+
return await Task.FromResult(result).ConfigureAwait(false);
119+
});
120+
121+
return auth;
122+
});
100123
/* ⬆️⬆️⬆️ Add this ⬆️⬆️⬆️ */
101124
}
102125
}

docs/openapi-out-of-proc.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,30 @@ namespace MyFunctionApp
102102
/* ⬇️⬇️⬇️ Add this ⬇️⬇️⬇️ */
103103
.ConfigureServices(services =>
104104
{
105-
services.AddSingleton<IOpenApiHttpTriggerAuthorization, MyOpenApiHttpTriggerAuthorization>();
105+
services.AddSingleton<IOpenApiHttpTriggerAuthorization>(_ =>
106+
{
107+
var auth = new OpenApiHttpTriggerAuthorization(async req =>
108+
{
109+
var result = default(OpenApiAuthorizationResult);
110+
111+
var authtoken = (string)req.Headers["Authorization"];
112+
if (authtoken.IsNullOrWhiteSpace())
113+
{
114+
result = new OpenApiAuthorizationResult()
115+
{
116+
StatusCode = HttpStatusCode.Unauthorized,
117+
ContentType = "text/plain",
118+
Payload = "Unauthorized",
119+
};
120+
121+
return await Task.FromResult(result).ConfigureAwait(false);
122+
}
123+
124+
return await Task.FromResult(result).ConfigureAwait(false);
125+
});
126+
127+
return auth;
128+
});
106129
})
107130
/* ⬆️⬆️⬆️ Add this ⬆️⬆️⬆️ */
108131
.Build();
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
using System.Globalization;
2+
using System.Linq;
3+
using System.Net;
14
using System.Threading.Tasks;
25

36
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
47
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
8+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
59

610
namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc.Configurations
711
{
@@ -11,9 +15,47 @@ public override async Task<OpenApiAuthorizationResult> AuthorizeAsync(IHttpReque
1115
{
1216
var result = default(OpenApiAuthorizationResult);
1317

14-
// Put your custom logic here!
18+
/* // ⬇️⬇️⬇️ This is a sample custom authorisation logic ⬇️⬇️⬇️
19+
var authtoken = (string)req.Headers["Authorization"];
20+
if (authtoken.IsNullOrWhiteSpace())
21+
{
22+
result = new OpenApiAuthorizationResult()
23+
{
24+
StatusCode = HttpStatusCode.Unauthorized,
25+
ContentType = "text/plain",
26+
Payload = "Unauthorized",
27+
};
28+
29+
return await Task.FromResult(result).ConfigureAwait(false);
30+
}
31+
32+
if (authtoken.StartsWith("Bearer", ignoreCase: true, CultureInfo.InvariantCulture) == false)
33+
{
34+
result = new OpenApiAuthorizationResult()
35+
{
36+
StatusCode = HttpStatusCode.Unauthorized,
37+
ContentType = "text/plain",
38+
Payload = "Invalid auth format",
39+
};
40+
41+
return await Task.FromResult(result).ConfigureAwait(false);
42+
}
43+
44+
var token = authtoken.Split(' ').Last();
45+
if (token != "secret")
46+
{
47+
result = new OpenApiAuthorizationResult()
48+
{
49+
StatusCode = HttpStatusCode.Forbidden,
50+
ContentType = "text/plain",
51+
Payload = "Invalid auth token",
52+
};
53+
54+
return await Task.FromResult(result).ConfigureAwait(false);
55+
}
56+
// ⬆️⬆️⬆️ This is a sample custom authorisation logic ⬆️⬆️⬆️ */
1557

1658
return await Task.FromResult(result).ConfigureAwait(false);
1759
}
1860
}
19-
}
61+
}

samples/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc/Program.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using System;
2+
using System.Threading.Tasks;
23

34
using AutoFixture;
45

56
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions;
6-
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc.Configurations;
77
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
88
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
99
using Microsoft.Extensions.DependencyInjection;
@@ -53,7 +53,24 @@ public static void Main()
5353

5454
return options;
5555
})
56-
.AddSingleton<IOpenApiHttpTriggerAuthorization, MyOpenApiHttpTriggerAuthorization>();
56+
.AddSingleton<IOpenApiHttpTriggerAuthorization>(_ =>
57+
{
58+
var auth = new OpenApiHttpTriggerAuthorization(async req =>
59+
{
60+
var result = default(OpenApiAuthorizationResult);
61+
62+
// ⬇️⬇️⬇️ Add your custom authorisation logic ⬇️⬇️⬇️
63+
//
64+
// CUSTOM AUTHORISATION LOGIC
65+
//
66+
// ⬆️⬆️⬆️ Add your custom authorisation logic ⬆️⬆️⬆️
67+
68+
return await Task.FromResult(result).ConfigureAwait(false);
69+
});
70+
71+
return auth;
72+
})
73+
;
5774
})
5875
.Build();
5976

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.InProc/Configurations/MyOpenApiHttpTriggerAuthorization.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public class MyOpenApiHttpTriggerAuthorization : DefaultOpenApiHttpTriggerAuthor
1414
public override async Task<OpenApiAuthorizationResult> AuthorizeAsync(IHttpRequestDataObject req)
1515
{
1616
var result = default(OpenApiAuthorizationResult);
17+
18+
/* // ⬇️⬇️⬇️ This is a sample custom authorisation logic ⬇️⬇️⬇️
1719
var authtoken = (string)req.Headers["Authorization"];
1820
if (authtoken.IsNullOrWhiteSpace())
1921
{
@@ -51,8 +53,9 @@ public override async Task<OpenApiAuthorizationResult> AuthorizeAsync(IHttpReque
5153
5254
return await Task.FromResult(result).ConfigureAwait(false);
5355
}
56+
// ⬆️⬆️⬆️ This is a sample custom authorisation logic ⬆️⬆️⬆️ */
5457

5558
return await Task.FromResult(result).ConfigureAwait(false);
5659
}
5760
}
58-
}
61+
}

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.InProc/Startup.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
using System;
2+
using System.Threading.Tasks;
23

34
using AutoFixture;
45

56
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
67
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
78
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
8-
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.InProc.Configurations;
99
using Microsoft.Extensions.DependencyInjection;
1010
using Microsoft.OpenApi.Models;
1111

@@ -49,8 +49,24 @@ public override void Configure(IFunctionsHostBuilder builder)
4949

5050
return options;
5151
})
52-
.AddSingleton<IOpenApiHttpTriggerAuthorization, MyOpenApiHttpTriggerAuthorization>();
52+
.AddSingleton<IOpenApiHttpTriggerAuthorization>(_ =>
53+
{
54+
var auth = new OpenApiHttpTriggerAuthorization(async req =>
55+
{
56+
var result = default(OpenApiAuthorizationResult);
57+
58+
// ⬇️⬇️⬇️ Add your custom authorisation logic ⬇️⬇️⬇️
59+
//
60+
// CUSTOM AUTHORISATION LOGIC
61+
//
62+
// ⬆️⬆️⬆️ Add your custom authorisation logic ⬆️⬆️⬆️
5363

64+
return await Task.FromResult(result).ConfigureAwait(false);
65+
});
66+
67+
return auth;
68+
})
69+
;
5470
}
5571
}
5672
}
Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
1-
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Functions;
2-
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
3-
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
4-
using Microsoft.Extensions.DependencyInjection;
5-
using Microsoft.Extensions.Hosting;
6-
7-
namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions
8-
{
9-
/// <summary>
10-
/// This represents the extensions entity to configure OpenAPI capability to Azure Functions out-of-process worker.
11-
/// </summary>
12-
public static class OpenApiHostBuilderExtensions
13-
{
14-
/// <summary>
15-
/// Configures to use OpenAPI features.
16-
/// </summary>
17-
/// <param name="hostBuilder"><see cref="IHostBuilder"/> instance.</param>
18-
/// <returns>Returns <see cref="IHostBuilder"/> instance.</returns>
19-
public static IHostBuilder ConfigureOpenApi(this IHostBuilder hostBuilder)
20-
{
21-
hostBuilder.ConfigureServices(services =>
22-
{
23-
services.AddSingleton<IOpenApiHttpTriggerContext, OpenApiHttpTriggerContext>();
24-
services.AddSingleton<IOpenApiTriggerFunction, OpenApiTriggerFunction>();
25-
// services.AddSingleton<DefaultOpenApiHttpTrigger, DefaultOpenApiHttpTrigger>();
26-
});
27-
28-
return hostBuilder;
29-
}
30-
}
31-
}
1+
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Functions;
2+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Hosting;
5+
6+
namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions
7+
{
8+
/// <summary>
9+
/// This represents the extensions entity to configure OpenAPI capability to Azure Functions out-of-process worker.
10+
/// </summary>
11+
public static class OpenApiHostBuilderExtensions
12+
{
13+
/// <summary>
14+
/// Configures to use OpenAPI features.
15+
/// </summary>
16+
/// <param name="hostBuilder"><see cref="IHostBuilder"/> instance.</param>
17+
/// <returns>Returns <see cref="IHostBuilder"/> instance.</returns>
18+
public static IHostBuilder ConfigureOpenApi(this IHostBuilder hostBuilder)
19+
{
20+
hostBuilder.ConfigureServices(services =>
21+
{
22+
services.AddSingleton<IOpenApiHttpTriggerContext, OpenApiHttpTriggerContext>();
23+
services.AddSingleton<IOpenApiTriggerFunction, OpenApiTriggerFunction>();
24+
//services.AddSingleton<DefaultOpenApiHttpTrigger, DefaultOpenApiHttpTrigger>();
25+
});
26+
27+
return hostBuilder;
28+
}
29+
}
30+
}

src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Attributes/OpenApiHttpTriggerAuthorizationIgnoreAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes
66
{
77
/// <summary>
8-
/// This represents the attribute entity for <see cref="IOpenApiConfigurationOptions"/> to be excluded from auto-loading.
8+
/// This represents the attribute entity for <see cref="IOpenApiHttpTriggerAuthorization"/> to be excluded from auto-loading.
99
/// </summary>
1010
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
1111
public class OpenApiHttpTriggerAuthorizationIgnoreAttribute : Attribute

0 commit comments

Comments
 (0)