Skip to content

Commit

Permalink
Setting AccessDeniedPath in AddMicrosoftIdentityUI. Warning fix for S…
Browse files Browse the repository at this point in the history
…A1400.

Updated unit tests related to #156.
  • Loading branch information
pmaytak committed May 15, 2020
1 parent 35a76fd commit 00ec54e
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 22 deletions.
3 changes: 0 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -515,9 +515,6 @@ dotnet_diagnostic.SA1312.severity = none
# SA1313: Parameter names should begin with lower-case letter
dotnet_diagnostic.SA1313.severity = none

# SA1400: Access modifier should be declared
dotnet_diagnostic.SA1400.severity = none

# SA1401: Fields should be private
dotnet_diagnostic.SA1401.severity = none

Expand Down
18 changes: 17 additions & 1 deletion src/Microsoft.Identity.Web.UI/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace Microsoft.Identity.Web.UI
Expand All @@ -14,14 +17,27 @@ public static class ServiceCollectionExtensions
/// <summary>
/// Adds a controller and Razor pages for the accounts management.
/// </summary>
/// <param name="builder">MVC Builder.</param>
/// <param name="builder">MVC builder.</param>
public static IMvcBuilder AddMicrosoftIdentityUI(this IMvcBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}

builder.ConfigureApplicationPartManager(apm =>
{
apm.FeatureProviders.Add(new MicrosoftIdentityAccountControllerFeatureProvider());
});

builder.Services.ConfigureAll<CookieAuthenticationOptions>(options =>
{
if (string.IsNullOrEmpty(options.AccessDeniedPath))
{
options.AccessDeniedPath = new PathString("/MicrosoftIdentity/Account/AccessDenied");
}
});

return builder;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
Expand Down Expand Up @@ -198,4 +199,4 @@ public static AuthenticationBuilder AddSignIn(
return builder;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static class WebAppServiceCollectionExtensions
/// <param name="openIdConnectScheme">Optional name for the open id connect authentication scheme
/// (by default OpenIdConnectDefaults.AuthenticationScheme). This can be specified when you want to support
/// several OpenIdConnect identity providers.</param>
/// <param name="cookieScheme">Optional name for the acookie uthentication scheme
/// <param name="cookieScheme">Optional name for the cookie authentication scheme
/// (by default OpenIdConnectDefaults.AuthenticationScheme). </param>
/// <param name="subscribeToOpenIdConnectMiddlewareDiagnosticsEvents">
/// Set to true if you want to debug, or just understand the OpenIdConnect events.
Expand Down Expand Up @@ -66,7 +66,7 @@ public static IServiceCollection AddSignIn(
/// <param name="openIdConnectScheme">Optional name for the open id connect authentication scheme
/// (by default OpenIdConnectDefaults.AuthenticationScheme). This can be specified when you want to support
/// several OpenIdConnect identity providers.</param>
/// <param name="cookieScheme">Optional name for the acookie uthentication scheme
/// <param name="cookieScheme">Optional name for the cookie authentication scheme
/// (by default OpenIdConnectDefaults.AuthenticationScheme). </param>
/// <param name="subscribeToOpenIdConnectMiddlewareDiagnosticsEvents">
/// Set to true if you want to debug, or just understand the OpenIdConnect events.
Expand Down Expand Up @@ -102,7 +102,8 @@ public static IServiceCollection AddSignIn(
/// several OpenIdConnect identity providers.</param>
/// <returns>The service collection for chaining.</returns>
/// <remarks>This method cannot be used with Azure AD B2C as, with B2C an initial scope needs
/// to be provided</remarks>
/// to be provided.
/// </remarks>
public static IServiceCollection AddWebAppCallsProtectedWebApi(
this IServiceCollection services,
IConfiguration configuration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ namespace Microsoft.Identity.Web.Test.Integration
#if !FROM_GITHUB_ACTION
public class AcquireTokenForAppIntegrationTests
{
TokenAcquisition _tokenAcquisition;
ServiceProvider _provider;
private TokenAcquisition _tokenAcquisition;
private ServiceProvider _provider;
private MsalTestTokenCacheProvider _msalTestTokenCacheProvider;
private IOptions<MicrosoftIdentityOptions> microsoftIdentityOptions;

Expand Down
42 changes: 30 additions & 12 deletions tests/Microsoft.Identity.Web.Test/WebApiExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -324,62 +324,80 @@ private IConfigurationSection GetConfigSection(string configSectionName)
}

[Fact]
public void AddProtectedWebApiCallsProtectedWebApi_WithConfigName()
public async Task AddProtectedWebApiCallsProtectedWebApi_WithConfigName()
{
var config = Substitute.For<IConfiguration>();
var tokenValidatedFuncMock = Substitute.For<Func<TokenValidatedContext, Task>>();

var services = new ServiceCollection()
.Configure<JwtBearerOptions>(_jwtBearerScheme, (options) =>
{
options.Events ??= new JwtBearerEvents();
options.Events.OnTokenValidated += tokenValidatedFuncMock;
})
.AddProtectedWebApiCallsProtectedWebApi(config, _configSectionName, _jwtBearerScheme);
var provider = services.BuildServiceProvider();

// Config bind actions added correctly
// Assert config bind actions added correctly
provider.GetRequiredService<IOptionsFactory<ConfidentialClientApplicationOptions>>().Create(string.Empty);
provider.GetRequiredService<IOptionsFactory<MicrosoftIdentityOptions>>().Create(string.Empty);

config.Received(2).GetSection(_configSectionName);

AddProtectedWebApiCallsProtectedWebApi_TestCommon(services, provider);
await AddProtectedWebApiCallsProtectedWebApi_TestCommon(services, provider, tokenValidatedFuncMock).ConfigureAwait(false);
}

[Fact]
public void AddProtectedWebApiCallsProtectedWebApi_WithConfigActions()
public async Task AddProtectedWebApiCallsProtectedWebApi_WithConfigActions()
{
var tokenValidatedFuncMock = Substitute.For<Func<TokenValidatedContext, Task>>();
var services = new ServiceCollection()
.Configure<JwtBearerOptions>(_jwtBearerScheme, (options) =>
{
options.Events ??= new JwtBearerEvents();
options.Events.OnTokenValidated += tokenValidatedFuncMock;
})
.AddProtectedWebApiCallsProtectedWebApi(_configureAppOptions, _configureMsOptions, _jwtBearerScheme);
var provider = services.BuildServiceProvider();

// Configure options actions added correctly
// Assert configure options actions added correctly
var configuredAppOptions = provider.GetServices<IConfigureOptions<ConfidentialClientApplicationOptions>>().Cast<ConfigureNamedOptions<ConfidentialClientApplicationOptions>>();
var configuredMsOptions = provider.GetServices<IConfigureOptions<MicrosoftIdentityOptions>>().Cast<ConfigureNamedOptions<MicrosoftIdentityOptions>>();

Assert.Contains(configuredAppOptions, o => o.Action == _configureAppOptions);
Assert.Contains(configuredMsOptions, o => o.Action == _configureMsOptions);

AddProtectedWebApiCallsProtectedWebApi_TestCommon(services, provider);
await AddProtectedWebApiCallsProtectedWebApi_TestCommon(services, provider, tokenValidatedFuncMock).ConfigureAwait(false);
}

private void AddProtectedWebApiCallsProtectedWebApi_TestCommon(IServiceCollection services, ServiceProvider provider)
private async Task AddProtectedWebApiCallsProtectedWebApi_TestCommon(IServiceCollection services, ServiceProvider provider, Func<TokenValidatedContext, Task> tokenValidatedFuncMock)
{
// Correct services added
// Assert correct services added
Assert.Contains(services, s => s.ServiceType == typeof(IHttpContextAccessor));
Assert.Contains(services, s => s.ServiceType == typeof(ITokenAcquisition));
Assert.Contains(services, s => s.ServiceType == typeof(IConfigureOptions<ConfidentialClientApplicationOptions>));
Assert.Contains(services, s => s.ServiceType == typeof(IConfigureOptions<MicrosoftIdentityOptions>));
Assert.Contains(services, s => s.ServiceType == typeof(IConfigureOptions<JwtBearerOptions>));

// JWT options added correctly
// Assert JWT options added correctly
var configuredJwtOptions = provider.GetService<IConfigureOptions<JwtBearerOptions>>() as ConfigureNamedOptions<JwtBearerOptions>;

Assert.Equal(_jwtBearerScheme, configuredJwtOptions.Name);

// Token validated event added correctly
// Assert token validated event added correctly
var jwtOptions = provider.GetRequiredService<IOptionsFactory<JwtBearerOptions>>().Create(_jwtBearerScheme);
var httpContext = HttpContextUtilities.CreateHttpContext();
var authScheme = new AuthenticationScheme(JwtBearerDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme, typeof(JwtBearerHandler));
var tokenValidatedContext = new TokenValidatedContext(httpContext, authScheme, jwtOptions) { SecurityToken = new JwtSecurityToken() };
var tokenValidatedContext = new TokenValidatedContext(httpContext, authScheme, jwtOptions)
{
SecurityToken = new JwtSecurityToken(),
Principal = new ClaimsPrincipal(),
};

jwtOptions.Events.TokenValidated(tokenValidatedContext);
await jwtOptions.Events.TokenValidated(tokenValidatedContext).ConfigureAwait(false);

// Assert events called
await tokenValidatedFuncMock.ReceivedWithAnyArgs().Invoke(Arg.Any<TokenValidatedContext>()).ConfigureAwait(false);
Assert.NotNull(httpContext.GetTokenUsedToCallWebAPI());
}

Expand Down

0 comments on commit 00ec54e

Please sign in to comment.