Skip to content

Commit aeeb271

Browse files
committed
removing support for Bearer scheme and adding FunctionsBearer
1 parent bbfdcb2 commit aeeb271

23 files changed

+248
-303
lines changed

.build/release.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
<Company>DarkLoop</Company>
77
<Copyright>DarkLoop - All rights reserved</Copyright>
88
<Product>DarkLoop's Azure Functions Authorization</Product>
9-
<IsPreview>false</IsPreview>
9+
<IsPreview>true</IsPreview>
1010
<AssemblyVersion>4.0.0.0</AssemblyVersion>
11-
<Version>4.0.1</Version>
11+
<Version>4.1.0</Version>
1212
<FileVersion>$(Version).0</FileVersion>
1313
<RepositoryUrl>https://github.com/dark-loop/functions-authorize</RepositoryUrl>
1414
<License>https://github.com/dark-loop/functions-authorize/blob/master/LICENSE</License>

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,5 @@ ASALocalRun/
328328

329329
# MFractors (Xamarin productivity tool) working folder
330330
.mfractor/
331+
/sample/SampleInProcFunctions.V4/Properties/ServiceDependencies/dl-inproc-func - Zip Deploy
332+
/sample/SampleIsolatedFunctions.V4/Properties/serviceDependencies.dl-isloated-func - Zip Deploy.json

ChangeLog.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Change log
2+
Change log stars with version 3.1.3
3+
4+
## 4.1.0
5+
- ### [Breaking] Removing support for `Bearer` scheme and adding `FunctionsBearer`
6+
Recent security updates in the Azure Functions runtime are clashing with the use of the default, well known `Bearer` scheme.<br/>
7+
One of the effects of this change is the portal not able to interact with the functions app to retrieve runtime information and in some cases not able to retrieve functions information.
8+
In the past this was not an issue and application was able to replace the default `Bearer` configuration to enable the functionality provided by this package.<br/>
9+
Starting from this version, using the default `AddJwtBearer` with no custom name, will produce an error. You will have 2 options: you can switch your app to use `AddJwtFunctionsBearer` method without providing any name which will map your configuration to the `FunctionsBearer` scheme, or you can use `AddJwtBearer("<your-custom-scheme>", ...)` to specify something different.
10+
11+
## 4.0.1
12+
Deprecating `DarkLoop.Azure.Functions.Authorize` package in favor of `DarkLoop.Azure.Functions.Authorization.InProcess` package.<br/>
13+
The functionality remains the same, it's just a way to keep package naming in sync.
14+
15+
## 4.0.0
16+
Starting from 4.0.0, support for Azure Functions V4 Isolated mode with ASPNET Core integration is added.
17+
The package is now split into two separate packages, one for each mode.
18+
19+
The package for Azure Functions V3+ In-Proc mode is now called `DarkLoop.Azure.Functions.Authorization.InProcess` and the package for Azure Functions V4 Isolated mode with ASPNET Core integration is called `DarkLoop.Azure.Functions.Authorize.Isolated`.
20+
21+
- ### .NET 6 support
22+
Starting with version 4.0.0, the package is now targeting .NET 6.0. This means that the package is no longer compatible with .NET 5 or lower. If you are using .NET 5 or lower, you should use version 3.1.3 of the package.
23+
24+
- ### DarkLoop.Azure.Functions.Authorize v4.0.0
25+
This package is published but is now deprecated in favor of `DarkLoop.Azure.Functions.Authorization.InProcess`. All it's functionality remains the same. It's just a way to keep package naming in sync.
26+
27+
- ### Introducing IFunctionsAuthorizationProvider interface
28+
The `IFunctionsAuthorizationProvider` interface is introduced to allow for custom authorization filter provisioning to the framework.
29+
By default the framework relies on decorating the function or type with `[FunctionAuthorize]`. You could skip this decoration and provide the middleware with an authorization filter sourced from your own mechanism, for example a database.
30+
At this moment this can be done only with Isolated mode even when the interface is defined in the shared package.<br/>
31+
Support for In-Process will be added in a future version, once source generators are introduced, as the in-process framework relies on Invocation Filters to enable authorization.
32+
Replacing the service in the application services would break the authorization for in-process mode at this point.
33+
34+
## 3.1.3
35+
3.1.3 and lower versions only support Azure Functions V3 In-Proc mode. Starting from 4.0.0, support for Azure Functions V4 Isolated mode with ASPNET Core integration is added.
36+
- ### Support for disabling `FunctionAuthorize` effect at the application level.
37+
Adding support for disabling the effect of `[FunctionAuthorize]` attribute at the application level.
38+
This is useful when wanting to disable authorization for a specific environment, such as local development.
39+
40+
When configuring services, you can now configure `FunctionsAuthorizationOptions`.
41+
```csharp
42+
builder.Services.Configure<FunctionsAuthorizationOptions>(options =>
43+
options.DisableAuthorization = Configuration.GetValue<bool>("AuthOptions:DisableAuthorization"));
44+
```
45+
46+
Optionally you can bind it to configuration to rely on providers like User Secrets or Azure App Configuration to disable and re-enable without having to restart your application:
47+
```csharp
48+
builder.Services.Configure<FunctionsAuthorizationOptions>(
49+
Configuration.GetSection("FunctionsAuthorization"));
50+
```
51+
52+
For function apps targeting .NET 7 or greater, you can also use `AuthorizationBuilder` to set this value:
53+
```csharp
54+
builder.Services
55+
.AddAuthorizationBuilder()
56+
.DisableAuthorization(Configuration.GetValue<bool>("AuthOptions:DisableAuthorization"));
57+
```
58+
59+
It's always recommended to encapsulate this logic within checks for environments to ensure that if the configuration setting is unintentionally moved to a non-desired environment, it would not affect security of our HTTP triggered functions. This change adds a helper method to identify if you are running the function app in the local environment:
60+
```csharp
61+
if (builder.IsLocalAuthorizationContext())
62+
{
63+
builder.Services.Configure<FunctionsAuthorizationOptions>(
64+
options => options.AuthorizationDisabled = true);
65+
}
66+
```
67+
68+
If you want to output warnings emitted by the library remember to set the log level to `Warning` or lower for `Darkloop` category in your `host.json` file:
69+
70+
```json
71+
{
72+
"logging": {
73+
"logLevel": {
74+
"DarkLoop": "Warning"
75+
}
76+
}
77+
}
78+
```
79+
80+
Thanks to [BenjaminWang1031](https://github.com/BenjaminWang1031) for the suggestion to add this functionality.
81+
82+
- #### Remove Functions bult-in JwtBearer configuration by default
83+
Azure Functions recently [added configuration](https://github.com/Azure/azure-functions-host/pull/9678) for issuer and audience validation for the default authentication flows, not the one supported by this package through `FunctionAuthorizeAttribute`, which interferes with token validation when using our own Bearer scheme token configuration.
84+
In prior versions, this package has functionality to clear Functions built-in configuration, but it was not enabled by default when using `AddJwtBearer(Action<JwtBearerOptions> configure, bool removeBuiltInConfig = false)`. Since the use of this package is commonly used for custom JWT token, the default value of `removeBuiltInConfig` is now `true`.

Functions-Authorize.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".root", ".root", "{3A9A7517
1414
ProjectSection(SolutionItems) = preProject
1515
.editorconfig = .editorconfig
1616
.gitignore = .gitignore
17+
ChangeLog.md = ChangeLog.md
1718
LICENSE = LICENSE
1819
NuGet.Config = NuGet.Config
1920
README.md = README.md

README.md

Lines changed: 2 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -17,80 +17,5 @@ This projects is open source and may be redistributed under the terms of the [Ap
1717
### Builds
1818
![master build status](https://dev.azure.com/darkloop/DarkLoop%20Core%20Library/_apis/build/status/Open%20Source/Functions%20Authorize%20-%20Pack?branchName=master)
1919

20-
## Change log
21-
Adding change log starting with version 3.1.3
22-
23-
### 4.0.1
24-
Deprecating `DarkLoop.Azure.Functions.Authorize` package in favor of `DarkLoop.Azure.Functions.Authorization.InProcess` package.<br/>
25-
The functionality remains the same, it's just a way to keep package naming in sync.
26-
27-
### 4.0.0
28-
Starting from 4.0.0, support for Azure Functions V4 Isolated mode with ASPNET Core integration is added.
29-
The package is now split into two separate packages, one for each mode.
30-
31-
The package for Azure Functions V3+ In-Proc mode is now called `DarkLoop.Azure.Functions.Authorization.InProcess` and the package for Azure Functions V4 Isolated mode with ASPNET Core integration is called `DarkLoop.Azure.Functions.Authorize.Isolated`.
32-
33-
- #### .NET 6 support
34-
Starting with version 4.0.0, the package is now targeting .NET 6.0. This means that the package is no longer compatible with .NET 5 or lower. If you are using .NET 5 or lower, you should use version 3.1.3 of the package.
35-
36-
- #### DarkLoop.Azure.Functions.Authorize v4.0.0
37-
This package is published but is now deprecated in favor of `DarkLoop.Azure.Functions.Authorization.InProcess`. All it's functionality remains the same. It's just a way to keep package naming in sync.
38-
39-
- #### Introducing IFunctionsAuthorizationProvider interface
40-
The `IFunctionsAuthorizationProvider` interface is introduced to allow for custom authorization filter provisioning to the framework.
41-
By default the framework relies on decorating the function or type with `[FunctionAuthorize]`. You could skip this decoration and provide the middleware with an authorization filter sourced from your own mechanism, for example a database.
42-
At this moment this can be done only with Isolated mode even when the interface is defined in the shared package.<br/>
43-
Support for In-Process will be added in a future version, once source generators are introduced, as the in-process framework relies on Invocation Filters to enable authorization.
44-
Replacing the service in the application services would break the authorization for in-process mode at this point.
45-
46-
### 3.1.3
47-
3.1.3 and lower versions only support Azure Functions V3 In-Proc mode. Starting from 4.0.0, support for Azure Functions V4 Isolated mode with ASPNET Core integration is added.
48-
- #### Support for disabling `FunctionAuthorize` effect at the application level.
49-
Adding support for disabling the effect of `[FunctionAuthorize]` attribute at the application level.
50-
This is useful when wanting to disable authorization for a specific environment, such as local development.
51-
52-
When configuring services, you can now configure `FunctionsAuthorizationOptions`.
53-
```csharp
54-
builder.Services.Configure<FunctionsAuthorizationOptions>(options =>
55-
options.DisableAuthorization = Configuration.GetValue<bool>("AuthOptions:DisableAuthorization"));
56-
```
57-
58-
Optionally you can bind it to configuration to rely on providers like User Secrets or Azure App Configuration to disable and re-enable without having to restart your application:
59-
```csharp
60-
builder.Services.Configure<FunctionsAuthorizationOptions>(
61-
Configuration.GetSection("FunctionsAuthorization"));
62-
```
63-
64-
For function apps targeting .NET 7 or greater, you can also use `AuthorizationBuilder` to set this value:
65-
```csharp
66-
builder.Services
67-
.AddAuthorizationBuilder()
68-
.DisableAuthorization(Configuration.GetValue<bool>("AuthOptions:DisableAuthorization"));
69-
```
70-
71-
It's always recommended to encapsulate this logic within checks for environments to ensure that if the configuration setting is unintentionally moved to a non-desired environment, it would not affect security of our HTTP triggered functions. This change adds a helper method to identify if you are running the function app in the local environment:
72-
```csharp
73-
if (builder.IsLocalAuthorizationContext())
74-
{
75-
builder.Services.Configure<FunctionsAuthorizationOptions>(
76-
options => options.AuthorizationDisabled = true);
77-
}
78-
```
79-
80-
If you want to output warnings emitted by the library remember to set the log level to `Warning` or lower for `Darkloop` category in your `host.json` file:
81-
82-
```json
83-
{
84-
"logging": {
85-
"logLevel": {
86-
"DarkLoop": "Warning"
87-
}
88-
}
89-
}
90-
```
91-
92-
Thanks to [BenjaminWang1031](https://github.com/BenjaminWang1031) for the suggestion to add this functionality.
93-
94-
- #### Remove Functions bult-in JwtBearer configuration by default
95-
Azure Functions recently [added configuration](https://github.com/Azure/azure-functions-host/pull/9678) for issuer and audience validation for the default authentication flows, not the one supported by this package through `FunctionAuthorizeAttribute`, which interferes with token validation when using our own Bearer scheme token configuration.
96-
In prior versions, this package has functionality to clear Functions built-in configuration, but it was not enabled by default when using `AddJwtBearer(Action<JwtBearerOptions> configure, bool removeBuiltInConfig = false)`. Since the use of this package is commonly used for custom JWT token, the default value of `removeBuiltInConfig` is now `true`.
20+
## Change Log
21+
You can access the change log [here](https://github.com/dark-loop/functions-authorize/blob/master/ChangeLog.md).

sample/SampleInProcFunctions.V4/SampleInProcFunctions.V4.csproj

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,22 @@
1010
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
1111
</PropertyGroup>
1212

13+
<ItemGroup>
14+
<None Remove="Properties\ServiceDependencies\dl-inproc-func - Zip Deploy\profile.arm.json" />
15+
</ItemGroup>
16+
1317
<ItemGroup>
1418
<PackageReference Include="Microsoft.AspNetCore.Authorization.Policy" Version="2.2.0" />
1519
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
1620
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
17-
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.2" />
21+
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="[4.3.0,)" />
1822
</ItemGroup>
23+
1924
<ItemGroup>
2025
<ProjectReference Include="..\..\src\in-proc\DarkLoop.Azure.Functions.Authorization.InProcess.csproj" />
2126
<ProjectReference Include="..\..\test\Common.Tests\Common.Tests.csproj" />
2227
</ItemGroup>
28+
2329
<ItemGroup>
2430
<None Update="host.json">
2531
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -29,4 +35,5 @@
2935
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
3036
</None>
3137
</ItemGroup>
38+
3239
</Project>

sample/SampleInProcFunctions.V4/Startup.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ public override void Configure(IFunctionsHostBuilder builder)
2424
builder.Services
2525
.AddFunctionsAuthentication(options =>
2626
{
27-
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
28-
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
27+
options.DefaultScheme = JwtFunctionsBearerDefaults.AuthenticationScheme;
28+
options.DefaultAuthenticateScheme = JwtFunctionsBearerDefaults.AuthenticationScheme;
29+
options.DefaultChallengeScheme = JwtFunctionsBearerDefaults.AuthenticationScheme;
2930
})
30-
.AddJwtBearer(options =>
31+
.AddJwtFunctionsBearer(options =>
3132
{
3233
// this line is here to bypass the token validation
3334
// and test the functionality of this library.
@@ -37,16 +38,16 @@ public override void Configure(IFunctionsHostBuilder builder)
3738

3839
// this is what you should look for in a real-world scenario
3940
// comment the lines if you cloned this repository and want to test the library
40-
options.Authority = "https://login.microsoftonline.com/<your-tenant>";
41-
options.Audience = "<your-audience>";
42-
options.TokenValidationParameters = new TokenValidationParameters
43-
{
44-
ValidateIssuer = true,
45-
ValidateAudience = true,
46-
ValidateLifetime = true,
47-
ValidateIssuerSigningKey = true,
48-
};
49-
}, true);
41+
//options.Authority = "https://login.microsoftonline.com/<your-tenant>";
42+
//options.Audience = "<your-audience>";
43+
//options.TokenValidationParameters = new TokenValidationParameters
44+
//{
45+
// ValidateIssuer = true,
46+
// ValidateAudience = true,
47+
// ValidateLifetime = true,
48+
// ValidateIssuerSigningKey = true,
49+
//};
50+
});
5051

5152
builder.Services.AddFunctionsAuthorization(options =>
5253
{
@@ -65,7 +66,7 @@ public override void Configure(IFunctionsHostBuilder builder)
6566

6667
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
6768
{
68-
builder.ConfigurationBuilder.AddUserSecrets<Startup>(false, reloadOnChange: true);
69+
builder.ConfigurationBuilder.AddUserSecrets<Startup>(true, reloadOnChange: true);
6970

7071
Configuration = builder.ConfigurationBuilder.Build();
7172

sample/SampleInProcFunctions.V4/host.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
}
99
},
1010
"logLevel": {
11-
"Darkloop": "Information"
11+
"Darkloop": "Information",
12+
"Microsoft": "Information"
1213
}
1314
}
1415
}

sample/SampleIsolatedFunctions.V4/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ publish/
144144
# Publish Web Output
145145
*.[Pp]ublish.xml
146146
*.azurePubxml
147+
*.arm.json
147148
# TODO: Comment the next line if you want to checkin your web deploy settings
148149
# but database connection strings (with potential passwords) will be unencrypted
149150
#*.pubxml

sample/SampleIsolatedFunctions.V4/Program.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System.IdentityModel.Tokens.Jwt;
66
using Common.Tests;
7+
using DarkLoop.Azure.Functions.Authorization;
78
using Microsoft.AspNetCore.Authentication.JwtBearer;
89
using Microsoft.Azure.Functions.Worker;
910
using Microsoft.Extensions.DependencyInjection;
@@ -29,8 +30,8 @@
2930
.ConfigureServices(services =>
3031
{
3132
services
32-
.AddFunctionsAuthentication(JwtBearerDefaults.AuthenticationScheme)
33-
.AddJwtBearer(options =>
33+
.AddFunctionsAuthentication(JwtFunctionsBearerDefaults.AuthenticationScheme)
34+
.AddJwtFunctionsBearer(options =>
3435
{
3536
// this line is here to bypass the token validation
3637
// and test the functionality of this library.

0 commit comments

Comments
 (0)