Skip to content

Commit

Permalink
Update to allow rolesclaim to be set in configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonpollett committed Nov 8, 2018
1 parent 67dfe76 commit 8911f32
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/Microsoft.Health.Fhir.Api/Modules/SecurityModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------

using System.IdentityModel.Tokens.Jwt;
using EnsureThat;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
Expand Down Expand Up @@ -33,6 +34,9 @@ public void Load(IServiceCollection services)

services.AddSingleton<IAuthorizationPolicyProvider, AuthorizationPolicyProvider>();

// Set the token handler to not do auto inbound mapping. (e.g. "roles" -> "http://schemas.microsoft.com/ws/2008/06/identity/claims/role")
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

if (_securityConfiguration.Enabled)
{
services.AddAuthentication(options =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static IEnumerable<object[]> GetIncompatibleRoleDataForAction(ResourceAct

private static ClaimsPrincipal GetClaimsPrincipalForRoles(params string[] roles)
{
var claimsId = new ClaimsIdentity(roles.Select(r => new Claim(ClaimTypes.Role, r)));
var claimsId = new ClaimsIdentity(roles.Select(r => new Claim("roles", r)));
return new ClaimsPrincipal(new List<ClaimsIdentity> { claimsId });
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.Health.Fhir.Core.Configs
{
public class AuthorizationConfiguration
{
public const string RolesClaim = "roles";
public string RolesClaim { get; set; } = "roles";

public bool Enabled { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ public class RoleBasedAuthorizationPolicy : IAuthorizationPolicy
{
private readonly Dictionary<string, Role> _roles;
private readonly Dictionary<string, IEnumerable<ResourceAction>> _roleNameToResourceActions;
private AuthorizationConfiguration _authorizationConfiguration;

public RoleBasedAuthorizationPolicy(AuthorizationConfiguration authorizationConfiguration)
{
EnsureArg.IsNotNull(authorizationConfiguration, nameof(authorizationConfiguration));

_authorizationConfiguration = authorizationConfiguration;
_roles = authorizationConfiguration.Roles.ToDictionary(r => r.Name, StringComparer.InvariantCultureIgnoreCase);
_roleNameToResourceActions = _roles.Select(kvp => KeyValuePair.Create(kvp.Key, kvp.Value.ResourcePermissions.Select(rp => rp.Actions).SelectMany(x => x))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
Expand All @@ -41,7 +43,7 @@ public bool HasPermission(ClaimsPrincipal user, ResourceAction action)
private IEnumerable<ResourceAction> GetRolesAndActions(ClaimsPrincipal user)
{
var roles = user.Claims
.Where(claim => (claim.Type == ClaimTypes.Role || claim.Type == AuthorizationConfiguration.RolesClaim) && _roles.ContainsKey(claim.Value))
.Where(claim => claim.Type == _authorizationConfiguration.RolesClaim && _roles.ContainsKey(claim.Value))
.Select(claim => _roles[claim.Value]);

var actions = roles.Select(r => _roleNameToResourceActions[r.Name]).SelectMany(x => x).Distinct();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public static IServiceCollection AddDevelopmentIdentityProvider(this IServiceCol
EnsureArg.IsNotNull(services, nameof(services));
EnsureArg.IsNotNull(configuration, nameof(configuration));

var authorizationConfiguration = new AuthorizationConfiguration();
configuration.GetSection("FhirServer:Security:Authorization").Bind(authorizationConfiguration);

var developmentIdentityProviderConfiguration = new DevelopmentIdentityProviderConfiguration();
configuration.GetSection("DevelopmentIdentityProvider").Bind(developmentIdentityProviderConfiguration);
services.AddSingleton(Options.Create(developmentIdentityProviderConfiguration));
Expand All @@ -46,9 +49,9 @@ public static IServiceCollection AddDevelopmentIdentityProvider(this IServiceCol
{
new ApiResource(
DevelopmentIdentityProviderConfiguration.Audience,
claimTypes: new List<string>() { ClaimTypes.Role, ClaimTypes.Name, ClaimTypes.NameIdentifier })
claimTypes: new List<string>() { authorizationConfiguration.RolesClaim, ClaimTypes.Name, ClaimTypes.NameIdentifier })
{
UserClaims = { AuthorizationConfiguration.RolesClaim },
UserClaims = { authorizationConfiguration.RolesClaim },
},
})
.AddTestUsers(developmentIdentityProviderConfiguration.Users?.Select(user =>
Expand All @@ -58,7 +61,7 @@ public static IServiceCollection AddDevelopmentIdentityProvider(this IServiceCol
Password = user.Id,
IsActive = true,
SubjectId = user.Id,
Claims = user.Roles.Select(r => new Claim(AuthorizationConfiguration.RolesClaim, r)).ToList(),
Claims = user.Roles.Select(r => new Claim(authorizationConfiguration.RolesClaim, r)).ToList(),
}).ToList())
.AddInMemoryClients(
developmentIdentityProviderConfiguration.ClientApplications.Select(
Expand All @@ -77,7 +80,7 @@ public static IServiceCollection AddDevelopmentIdentityProvider(this IServiceCol
AllowedScopes = { DevelopmentIdentityProviderConfiguration.Audience },

// app roles that the client app may have
Claims = applicationConfiguration.Roles.Select(r => new Claim(AuthorizationConfiguration.RolesClaim, r)).Concat(new[] { new Claim("appid", applicationConfiguration.Id) }).ToList(),
Claims = applicationConfiguration.Roles.Select(r => new Claim(authorizationConfiguration.RolesClaim, r)).Concat(new[] { new Claim("appid", applicationConfiguration.Id) }).ToList(),

ClientClaimsPrefix = string.Empty,
}));
Expand Down

0 comments on commit 8911f32

Please sign in to comment.