Skip to content
This repository has been archived by the owner on Jul 31, 2024. It is now read-only.

Commit

Permalink
Clarify semantics of resource validator and scope parser (#4452)
Browse files Browse the repository at this point in the history
* attempt to clarify semantics

* another possible improvement?

* minor feedback

* make individual scope validation easier

* update other hosts to match resource changes

* updates from code review/testing
  • Loading branch information
brockallen authored Jun 12, 2020
1 parent 881369d commit 63217ae
Show file tree
Hide file tree
Showing 59 changed files with 552 additions and 430 deletions.
20 changes: 10 additions & 10 deletions src/AspNetIdentity/host/Configuration/ClientsConsole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static IEnumerable<Client> Get()
ClientId = "client",
ClientSecrets = {new Secret("secret".Sha256())},
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = { "scope1", "scope2", IdentityServerConstants.LocalApi.ScopeName}
AllowedScopes = { "resource1.scope1", "resource2.scope1", IdentityServerConstants.LocalApi.ScopeName}
},

///////////////////////////////////////////
Expand Down Expand Up @@ -60,7 +60,7 @@ public static IEnumerable<Client> Get()

AccessTokenType = AccessTokenType.Jwt,
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = { "scope1", "scope2" }
AllowedScopes = { "resource1.scope1", "resource2.scope1" }
},

///////////////////////////////////////////
Expand All @@ -86,7 +86,7 @@ public static IEnumerable<Client> Get()
},

AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = { "scope1", "scope2" }
AllowedScopes = { "resource1.scope1", "resource2.scope1" }
},

///////////////////////////////////////////
Expand All @@ -97,7 +97,7 @@ public static IEnumerable<Client> Get()
ClientId = "client.custom",
ClientSecrets = {new Secret("secret".Sha256())},
AllowedGrantTypes = {"custom", "custom.nosubject"},
AllowedScopes = { "scope1", "scope2" }
AllowedScopes = { "resource1.scope1", "resource2.scope1" }
},

///////////////////////////////////////////
Expand All @@ -113,7 +113,7 @@ public static IEnumerable<Client> Get()
{
IdentityServerConstants.StandardScopes.OpenId,
"custom.profile",
"scope1", "scope2"
"resource1.scope1", "resource2.scope1"
}
},

Expand All @@ -130,7 +130,7 @@ public static IEnumerable<Client> Get()
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Email,
"scope1", "scope2"
"resource1.scope1", "resource2.scope1"
}
},

Expand All @@ -151,7 +151,7 @@ public static IEnumerable<Client> Get()
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"scope1", "scope2"
"resource1.scope1", "resource2.scope1"
}
},
///////////////////////////////////////////
Expand All @@ -173,7 +173,7 @@ public static IEnumerable<Client> Get()
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"scope1", "scope2"
"resource1.scope1", "resource2.scope1"
}
},

Expand All @@ -186,7 +186,7 @@ public static IEnumerable<Client> Get()
ClientId = "roclient.reference",
ClientSecrets = {new Secret("secret".Sha256())},
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
AllowedScopes = {"scope1", "scope2"},
AllowedScopes = { "resource1.scope1", "resource2.scope1" },
AccessTokenType = AccessTokenType.Reference
},

Expand All @@ -208,7 +208,7 @@ public static IEnumerable<Client> Get()
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"scope1", "scope2"
"resource1.scope1", "resource2.scope1"
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/AspNetIdentity/host/Configuration/ClientsWeb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public static class ClientsWeb
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"scope1",
"scope2",
"resource1.scope1",
"resource2.scope1",
"transaction"
};

Expand Down
25 changes: 12 additions & 13 deletions src/AspNetIdentity/host/Configuration/Resources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,20 @@ public class Resources
public static readonly IEnumerable<ApiScope> ApiScopes =
new[]
{
// local feature
// local API scope
new ApiScope(LocalApi.ScopeName),

// some generic scopes
new ApiScope("scope1"),
new ApiScope("scope2"),
// resource specific scopes
new ApiScope("resource1.scope1"),
new ApiScope("resource2.scope1"),

// a scope without resource association
new ApiScope("scope3"),

// a scope shared by multiple resources
new ApiScope("shared.scope"),

// used as a dynamic scope
// a parameterized scope
new ApiScope("transaction", "Transaction")
{
Description = "Some Transaction"
Expand All @@ -48,15 +52,11 @@ public class Resources
public static readonly IEnumerable<ApiResource> ApiResources =
new[]
{
// simple version with ctor
new ApiResource("resource1", "Resource 1")
{
// this is needed for introspection when using reference tokens
ApiSecrets = { new Secret("secret".Sha256()) },

//AllowedSigningAlgorithms = { "RS256", "ES256" }

Scopes = { "scope1", "shared.scope" }
Scopes = { "resource1.scope1", "shared.scope" }
},

// expanded version if more control is needed
Expand All @@ -67,15 +67,14 @@ public class Resources
new Secret("secret".Sha256())
},

//AllowedSigningAlgorithms = { "PS256", "ES256", "RS256" },

// additional claims to put into access token
UserClaims =
{
JwtClaimTypes.Name,
JwtClaimTypes.Email
},

Scopes = { "scope2", "shared.scope" }
Scopes = { "resource2.scope1", "shared.scope" }
}
};
}
Expand Down
14 changes: 7 additions & 7 deletions src/AspNetIdentity/host/Quickstart/Consent/ConsentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)
grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };

// emit event
await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.ScopeValues));
await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));
}
// user clicked 'yes' - validate the data
else if (model?.Button == "yes")
Expand All @@ -131,7 +131,7 @@ private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)
};

// emit event
await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.ScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));
await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));
}
else
{
Expand Down Expand Up @@ -199,10 +199,10 @@ private ConsentViewModel CreateConsentViewModel(
var apiScopes = new List<ScopeViewModel>();
foreach(var parsedScope in request.ValidatedResources.ParsedScopes)
{
var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.Name);
var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);
if (apiScope != null)
{
var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.Value) || model == null);
var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);
apiScopes.Add(scopeVm);
}
}
Expand Down Expand Up @@ -231,14 +231,14 @@ private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool chec
public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)
{
var displayName = apiScope.DisplayName ?? apiScope.Name;
if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParameterValue))
if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))
{
displayName += ":" + parsedScopeValue.ParameterValue;
displayName += ":" + parsedScopeValue.ParsedParameter;
}

return new ScopeViewModel
{
Value = parsedScopeValue.Value,
Value = parsedScopeValue.RawValue,
DisplayName = displayName,
Description = apiScope.Description,
Emphasize = apiScope.Emphasize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.


namespace IdentityServer4.Quickstart.UI.Device
namespace IdentityServer4.Quickstart.UI
{
public class DeviceAuthorizationInputModel : ConsentInputModel
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.


namespace IdentityServer4.Quickstart.UI.Device
namespace IdentityServer4.Quickstart.UI
{
public class DeviceAuthorizationViewModel : ConsentViewModel
{
Expand Down
12 changes: 6 additions & 6 deletions src/AspNetIdentity/host/Quickstart/Device/DeviceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace IdentityServer4.Quickstart.UI.Device
namespace IdentityServer4.Quickstart.UI
{
[Authorize]
[SecurityHeaders]
Expand Down Expand Up @@ -91,7 +91,7 @@ private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInput
grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };

// emit event
await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.ScopeValues));
await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));
}
// user clicked 'yes' - validate the data
else if (model.Button == "yes")
Expand All @@ -113,7 +113,7 @@ private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInput
};

// emit event
await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.ScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));
await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));
}
else
{
Expand Down Expand Up @@ -175,10 +175,10 @@ private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, Dev
var apiScopes = new List<ScopeViewModel>();
foreach (var parsedScope in request.ValidatedResources.ParsedScopes)
{
var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.Name);
var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);
if (apiScope != null)
{
var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.Value) || model == null);
var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);
apiScopes.Add(scopeVm);
}
}
Expand Down Expand Up @@ -208,7 +208,7 @@ public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, Ap
{
return new ScopeViewModel
{
Value = parsedScopeValue.Value,
Value = parsedScopeValue.RawValue,
// todo: use the parsed scope value in the display?
DisplayName = apiScope.DisplayName ?? apiScope.Name,
Description = apiScope.Description,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@model IdentityServer4.Quickstart.UI.Device.DeviceAuthorizationViewModel
@model DeviceAuthorizationViewModel

<div class="page-device-confirmation">
<div class="lead">
Expand Down
35 changes: 0 additions & 35 deletions src/EntityFramework/host/Extensions/ExtensionGrantValidator.cs

This file was deleted.

This file was deleted.

Loading

0 comments on commit 63217ae

Please sign in to comment.