Skip to content

Commit eab87af

Browse files
committed
check if we are hosted in azure
1 parent a786c7e commit eab87af

4 files changed

Lines changed: 123 additions & 10 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ There are some predefined providers in this package. If you need your own or wan
164164

165165
### `EasyAuthWithAuthMeService`
166166

167-
This is a slightly special provider. This provider cannot be configured. You can only turn it on or off. It also does **not** implement the 'IEasyAuthAuthentificationService'. This provider is for development. A developer can create a JSON with the content of the `/.auth/me` endpoint of an EasyAuth Azure Web App. So you don't need a connection to the internet or azure for development and just use your local things.
167+
This is a slightly special provider. This provider cannot be configured. You can only turn it on or off. It also does **not** implement the 'IEasyAuthAuthentificationService'. This provider is for development.
168+
It automatic disable it selfes, if you has configured azure easy auth feature.
169+
A developer can create a JSON with the content of the `/.auth/me` endpoint of an EasyAuth Azure Web App. So you don't need a connection to the internet or azure for development and just use your local things.
168170
You must only configure an Azure Web App with Authentification and browse the path:
169171

170172
`https://hostnameOfYourWebSite/.auth/me`

src/KK.AspNetCore.EasyAuthAuthentication/EasyAuthAuthenticationHandler.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace KK.AspNetCore.EasyAuthAuthentication
1010
using KK.AspNetCore.EasyAuthAuthentication.Services;
1111
using Microsoft.AspNetCore.Authentication;
1212
using Microsoft.AspNetCore.Http;
13+
using Microsoft.Extensions.Configuration;
1314
using Microsoft.Extensions.Logging;
1415
using Microsoft.Extensions.Options;
1516

@@ -24,13 +25,14 @@ public class EasyAuthAuthenticationHandler : AuthenticationHandler<EasyAuthAuthe
2425
private static readonly Func<IHeaderDictionary, string, bool> IsHeaderSet =
2526
(headers, headerName) => !string.IsNullOrEmpty(headers[headerName].ToString());
2627

27-
private static readonly Func<IHeaderDictionary, ClaimsPrincipal, HttpRequest, EasyAuthAuthenticationOptions, bool> CanUseEasyAuthJson =
28+
private static Func<IHeaderDictionary, ClaimsPrincipal, HttpRequest, EasyAuthAuthenticationOptions, bool> CanUseEasyAuthJson =
2829
(headers, user, request, options) =>
2930
IsContextUserNotAuthenticated(user)
3031
&& !IsHeaderSet(headers, AuthTokenHeaderNames.AADIdToken)
3132
&& request.Path != "/" + $"{options.AuthEndpoint}";
3233

3334
private readonly IEnumerable<IEasyAuthAuthentificationService> authenticationServices;
35+
private readonly IConfiguration appConfiguration;
3436

3537
/// <summary>
3638
/// Initializes a new instance of the <see cref="EasyAuthAuthenticationHandler"/> class.
@@ -45,7 +47,31 @@ public EasyAuthAuthenticationHandler(
4547
IEnumerable<IEasyAuthAuthentificationService> authenticationServices,
4648
ILoggerFactory logger,
4749
UrlEncoder encoder,
48-
ISystemClock clock) : base(options, logger, encoder, clock) => this.authenticationServices = authenticationServices;
50+
ISystemClock clock,
51+
IConfiguration appConfiguration) : base(options, logger, encoder, clock)
52+
{
53+
this.authenticationServices = authenticationServices;
54+
this.appConfiguration = appConfiguration;
55+
this.SetupHandler();
56+
}
57+
58+
private void SetupHandler()
59+
{
60+
var authEnabled = this.appConfiguration.GetValue<bool?>("APPSETTING_WEBSITE_AUTH_ENABLED");
61+
var allowAnoymos = this.appConfiguration.GetValue<string?>("APPSETTING_WEBSITE_AUTH_UNAUTHENTICATED_ACTION") == "AllowAnonymous" ? true : false;
62+
if(authEnabled == null || authEnabled == false)
63+
{
64+
// auth is turned of. So hopefully the user is in local debugging.
65+
return;
66+
}
67+
if (allowAnoymos == true)
68+
{
69+
this.Logger.LogError("Don't allow anonymous requests! The easy auth extension don't check the token!");
70+
throw new ArgumentException("Don't allow anonymous requests");
71+
}
72+
// disable the local auth.me json in azure.
73+
CanUseEasyAuthJson = (h, u, r, o) => false;
74+
}
4975

5076
/// <inheritdoc/>
5177
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()

test/KK.AspNetCore.EasyAuthAuthentication.Test/EasyAuthAuthenticationHandlerTest.cs

Lines changed: 91 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ namespace KK.AspNetCore.EasyAuthAuthentication.Test
1515
using Microsoft.AspNetCore.Authentication;
1616
using Microsoft.AspNetCore.Http;
1717
using Microsoft.AspNetCore.Http.Features;
18+
using Microsoft.Extensions.Configuration;
19+
using Microsoft.Extensions.Configuration.EnvironmentVariables;
1820
using Microsoft.Extensions.DependencyInjection;
1921
using Microsoft.Extensions.Logging;
2022
using Microsoft.Extensions.Logging.Abstractions;
@@ -35,6 +37,11 @@ public class EasyAuthAuthenticationHandlerTest
3537
public async Task IfAnProviderIsEnabledUseEnabledProvider()
3638
{
3739
// Arrange
40+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_ENABLED", "True");
41+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_UNAUTHENTICATED_ACTION", "RedirectToLoginPage");
42+
var configBuilder = new ConfigurationBuilder();
43+
configBuilder.AddEnvironmentVariables();
44+
var config = configBuilder.Build();
3845
var options = new EasyAuthAuthenticationOptions();
3946
options.AddProviderOptions(new ProviderOptions("TestProvider") { Enabled = true });
4047

@@ -46,7 +53,7 @@ public async Task IfAnProviderIsEnabledUseEnabledProvider()
4653
var monitor = services.GetRequiredService<IOptionsMonitor<EasyAuthAuthenticationOptions>>();
4754

4855

49-
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock);
56+
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock, config);
5057
var schema = new AuthenticationScheme(EasyAuthAuthenticationDefaults.AuthenticationScheme, EasyAuthAuthenticationDefaults.DisplayName, typeof(EasyAuthAuthenticationHandler));
5158
var httpContext = new DefaultHttpContext();
5259
await handler.InitializeAsync(schema, httpContext);
@@ -64,6 +71,11 @@ public async Task IfAnProviderIsEnabledUseEnabledProvider()
6471
public async Task IfAnProviderIsdisabledSkipProvider()
6572
{
6673
// Arrange
74+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_ENABLED", "True");
75+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_UNAUTHENTICATED_ACTION", "RedirectToLoginPage");
76+
var configBuilder = new ConfigurationBuilder();
77+
configBuilder.AddEnvironmentVariables();
78+
var config = configBuilder.Build();
6779
var options = new EasyAuthAuthenticationOptions();
6880
options.AddProviderOptions(new ProviderOptions("TestProvider") { Enabled = false });
6981

@@ -75,7 +87,7 @@ public async Task IfAnProviderIsdisabledSkipProvider()
7587
var monitor = services.GetRequiredService<IOptionsMonitor<EasyAuthAuthenticationOptions>>();
7688

7789

78-
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock);
90+
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock, config);
7991
var schema = new AuthenticationScheme(EasyAuthAuthenticationDefaults.AuthenticationScheme, EasyAuthAuthenticationDefaults.DisplayName, typeof(EasyAuthAuthenticationHandler));
8092
var context = new DefaultHttpContext();
8193
// If this header is set the fallback with the local authme.json isn't used.
@@ -92,6 +104,11 @@ public async Task IfAnProviderIsdisabledSkipProvider()
92104
public async Task IfTheUserIsAlreadyAuthorizedTheAuthResultIsSuccess()
93105
{
94106
// Arrange
107+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_ENABLED", "True");
108+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_UNAUTHENTICATED_ACTION", "RedirectToLoginPage");
109+
var configBuilder = new ConfigurationBuilder();
110+
configBuilder.AddEnvironmentVariables();
111+
var config = configBuilder.Build();
95112
var options = new EasyAuthAuthenticationOptions();
96113
options.AddProviderOptions(new ProviderOptions("TestProvider") { Enabled = false });
97114

@@ -103,7 +120,7 @@ public async Task IfTheUserIsAlreadyAuthorizedTheAuthResultIsSuccess()
103120
var monitor = services.GetRequiredService<IOptionsMonitor<EasyAuthAuthenticationOptions>>();
104121

105122

106-
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock);
123+
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock,config);
107124
var schema = new AuthenticationScheme(EasyAuthAuthenticationDefaults.AuthenticationScheme, EasyAuthAuthenticationDefaults.DisplayName, typeof(EasyAuthAuthenticationHandler));
108125
var context = new DefaultHttpContext();
109126
// If this header is set the fallback with the local authme.json isn't used.
@@ -122,6 +139,11 @@ public async Task IfTheUserIsAlreadyAuthorizedTheAuthResultIsSuccess()
122139
public async Task DontCallTheFallBackIfTheRequestUrlEqualsTheAuthEndPoint()
123140
{
124141
// Arrange
142+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_ENABLED", "True");
143+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_UNAUTHENTICATED_ACTION", "RedirectToLoginPage");
144+
var configBuilder = new ConfigurationBuilder();
145+
configBuilder.AddEnvironmentVariables();
146+
var config = configBuilder.Build();
125147
var options = new EasyAuthAuthenticationOptions();
126148
options.AddProviderOptions(new ProviderOptions("TestProvider") { Enabled = false });
127149

@@ -133,7 +155,7 @@ public async Task DontCallTheFallBackIfTheRequestUrlEqualsTheAuthEndPoint()
133155
var monitor = services.GetRequiredService<IOptionsMonitor<EasyAuthAuthenticationOptions>>();
134156

135157

136-
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock);
158+
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock, config);
137159
var schema = new AuthenticationScheme(EasyAuthAuthenticationDefaults.AuthenticationScheme, EasyAuthAuthenticationDefaults.DisplayName, typeof(EasyAuthAuthenticationHandler));
138160
var context = new DefaultHttpContext();
139161

@@ -149,6 +171,11 @@ public async Task DontCallTheFallBackIfTheRequestUrlEqualsTheAuthEndPoint()
149171
public async Task CallTheFallBackIfTheRequestUrlNotEqualsTheAuthEndPoint()
150172
{
151173
// Arrange
174+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_ENABLED", "True");
175+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_UNAUTHENTICATED_ACTION", "RedirectToLoginPage");
176+
var configBuilder = new ConfigurationBuilder();
177+
configBuilder.AddEnvironmentVariables();
178+
var config = configBuilder.Build();
152179
var options = new EasyAuthAuthenticationOptions();
153180
options.AddProviderOptions(new ProviderOptions("TestProvider") { Enabled = false });
154181

@@ -160,7 +187,7 @@ public async Task CallTheFallBackIfTheRequestUrlNotEqualsTheAuthEndPoint()
160187
var monitor = services.GetRequiredService<IOptionsMonitor<EasyAuthAuthenticationOptions>>();
161188

162189

163-
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock);
190+
var handler = new EasyAuthAuthenticationHandler(monitor, this.providers, this.loggerFactory, this.urlEncoder, this.clock, config);
164191
var schema = new AuthenticationScheme(EasyAuthAuthenticationDefaults.AuthenticationScheme, EasyAuthAuthenticationDefaults.DisplayName, typeof(EasyAuthAuthenticationHandler));
165192
var context = new DefaultHttpContext();
166193

@@ -170,13 +197,18 @@ public async Task CallTheFallBackIfTheRequestUrlNotEqualsTheAuthEndPoint()
170197
var result = await handler.AuthenticateAsync();
171198
// Assert
172199
Assert.False(result.Succeeded);
173-
Assert.NotNull(result.Failure);
200+
Assert.True(result.None);
174201
}
175202

176203
[Fact]
177204
public async Task DontCallAProviderIfNotProviderIsRegistered()
178205
{
179206
// Arrange
207+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_ENABLED", "True");
208+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_UNAUTHENTICATED_ACTION", "RedirectToLoginPage");
209+
var configBuilder = new ConfigurationBuilder();
210+
configBuilder.AddEnvironmentVariables();
211+
var config = configBuilder.Build();
180212
var options = new EasyAuthAuthenticationOptions();
181213
options.AddProviderOptions(new ProviderOptions("TestProvider") { Enabled = false });
182214

@@ -188,7 +220,7 @@ public async Task DontCallAProviderIfNotProviderIsRegistered()
188220
var monitor = services.GetRequiredService<IOptionsMonitor<EasyAuthAuthenticationOptions>>();
189221

190222

191-
var handler = new EasyAuthAuthenticationHandler(monitor, new List<IEasyAuthAuthentificationService>(), this.loggerFactory, this.urlEncoder, this.clock);
223+
var handler = new EasyAuthAuthenticationHandler(monitor, new List<IEasyAuthAuthentificationService>(), this.loggerFactory, this.urlEncoder, this.clock, config);
192224
var schema = new AuthenticationScheme(EasyAuthAuthenticationDefaults.AuthenticationScheme, EasyAuthAuthenticationDefaults.DisplayName, typeof(EasyAuthAuthenticationHandler));
193225
var context = new DefaultHttpContext();
194226
// Act
@@ -198,6 +230,58 @@ public async Task DontCallAProviderIfNotProviderIsRegistered()
198230
Assert.False(result.Succeeded);
199231
}
200232

233+
[Fact]
234+
public void ErrorIfTheAuthIsEnabledButAnonymousRequestsAreAllowed()
235+
{
236+
// Arrange
237+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_ENABLED", "True");
238+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_UNAUTHENTICATED_ACTION", "AllowAnonymous");
239+
var configBuilder = new ConfigurationBuilder();
240+
configBuilder.AddEnvironmentVariables();
241+
var config = configBuilder.Build();
242+
var options = new EasyAuthAuthenticationOptions();
243+
options.AddProviderOptions(new ProviderOptions("TestProvider") { Enabled = false });
244+
245+
246+
var services = new ServiceCollection().AddOptions()
247+
.AddSingleton<IOptionsFactory<EasyAuthAuthenticationOptions>, OptionsFactory<EasyAuthAuthenticationOptions>>()
248+
.Configure<EasyAuthAuthenticationOptions>(EasyAuthAuthenticationDefaults.AuthenticationScheme, o => o.ProviderOptions = options.ProviderOptions)
249+
.BuildServiceProvider();
250+
var monitor = services.GetRequiredService<IOptionsMonitor<EasyAuthAuthenticationOptions>>();
251+
252+
Assert.Throws<ArgumentException>(() => new EasyAuthAuthenticationHandler(monitor, new List<IEasyAuthAuthentificationService>(), this.loggerFactory, this.urlEncoder, this.clock, config));
253+
}
254+
255+
[Fact]
256+
public async Task UseEasyAuthProviderIfAuthIsDisabled()
257+
{
258+
// Arrange
259+
System.Environment.SetEnvironmentVariable("APPSETTING_WEBSITE_AUTH_ENABLED", "False");
260+
var configBuilder = new ConfigurationBuilder();
261+
configBuilder.AddEnvironmentVariables();
262+
var config = configBuilder.Build();
263+
var options = new EasyAuthAuthenticationOptions();
264+
options.AddProviderOptions(new ProviderOptions("TestProvider") { Enabled = false });
265+
266+
267+
var services = new ServiceCollection().AddOptions()
268+
.AddSingleton<IOptionsFactory<EasyAuthAuthenticationOptions>, OptionsFactory<EasyAuthAuthenticationOptions>>()
269+
.Configure<EasyAuthAuthenticationOptions>(EasyAuthAuthenticationDefaults.AuthenticationScheme, o => o.ProviderOptions = options.ProviderOptions)
270+
.BuildServiceProvider();
271+
var monitor = services.GetRequiredService<IOptionsMonitor<EasyAuthAuthenticationOptions>>();
272+
273+
var handler = new EasyAuthAuthenticationHandler(monitor, new List<IEasyAuthAuthentificationService>(), this.loggerFactory, this.urlEncoder, this.clock, config);
274+
var schema = new AuthenticationScheme(EasyAuthAuthenticationDefaults.AuthenticationScheme, EasyAuthAuthenticationDefaults.DisplayName, typeof(EasyAuthAuthenticationHandler));
275+
var context = new DefaultHttpContext();
276+
// Act
277+
await handler.InitializeAsync(schema, context);
278+
var result = await handler.AuthenticateAsync();
279+
// Assert
280+
Assert.False(result.Succeeded); // The EasyAuth me service is currently hard to test, so we only can check if it's fails
281+
Assert.NotNull(result.Failure);
282+
Assert.Equal("An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.", result.Failure.Message);
283+
}
284+
201285
private class TestProvider : IEasyAuthAuthentificationService
202286
{
203287
public AuthenticateResult AuthUser(HttpContext context) => this.AuthUser(context, null);

test/KK.AspNetCore.EasyAuthAuthentication.Test/KK.AspNetCore.EasyAuthAuthentication.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.3" />
1011
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.1" />
1112
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
1213
<PackageReference Include="xunit" Version="2.4.1" />

0 commit comments

Comments
 (0)