mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 20:12:51 +08:00
* testing issue on train * check multiple claims of the same type for authorisation
This commit is contained in:
parent
1e48a97294
commit
9f7478c91f
@ -20,22 +20,22 @@ namespace Ocelot.Authorisation
|
|||||||
{
|
{
|
||||||
foreach (var required in routeClaimsRequirement)
|
foreach (var required in routeClaimsRequirement)
|
||||||
{
|
{
|
||||||
var value = _claimsParser.GetValue(claimsPrincipal.Claims, required.Key, string.Empty, 0);
|
var values = _claimsParser.GetValuesByClaimType(claimsPrincipal.Claims, required.Key);
|
||||||
|
|
||||||
if (value.IsError)
|
if (values.IsError)
|
||||||
{
|
{
|
||||||
return new ErrorResponse<bool>(value.Errors);
|
return new ErrorResponse<bool>(values.Errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.Data != null)
|
if (values.Data != null)
|
||||||
{
|
{
|
||||||
var authorised = value.Data == required.Value;
|
var authorised = values.Data.Contains(required.Value);
|
||||||
if (!authorised)
|
if (!authorised)
|
||||||
{
|
{
|
||||||
return new ErrorResponse<bool>(new List<Error>
|
return new ErrorResponse<bool>(new List<Error>
|
||||||
{
|
{
|
||||||
new ClaimValueNotAuthorisedError(
|
new ClaimValueNotAuthorisedError(
|
||||||
$"claim value: {value.Data} is not the same as required value: {required.Value} for type: {required.Key}")
|
$"claim value: {values.Data} is not the same as required value: {required.Value} for type: {required.Key}")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,66 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_fix_issue_240()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 51876,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
},
|
||||||
|
RouteClaimsRequirement =
|
||||||
|
{
|
||||||
|
{"Role", "User"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var users = new List<TestUser>
|
||||||
|
{
|
||||||
|
new TestUser
|
||||||
|
{
|
||||||
|
Username = "test",
|
||||||
|
Password = "test",
|
||||||
|
SubjectId = "registered|1231231",
|
||||||
|
Claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim("Role", "AdminUser"),
|
||||||
|
new Claim("Role", "User")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt, users))
|
||||||
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
|
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_servicebuilder = new WebHostBuilder()
|
_servicebuilder = new WebHostBuilder()
|
||||||
@ -335,7 +395,75 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_identityServerBuilder.Start();
|
_identityServerBuilder.Start();
|
||||||
|
|
||||||
_steps.VerifyIdentiryServerStarted(url);
|
_steps.VerifyIdentiryServerStarted(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType, List<TestUser> users)
|
||||||
|
{
|
||||||
|
_identityServerBuilder = new WebHostBuilder()
|
||||||
|
.UseUrls(url)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.UseUrls(url)
|
||||||
|
.ConfigureServices(services =>
|
||||||
|
{
|
||||||
|
services.AddLogging();
|
||||||
|
services.AddIdentityServer()
|
||||||
|
.AddDeveloperSigningCredential()
|
||||||
|
.AddInMemoryApiResources(new List<ApiResource>
|
||||||
|
{
|
||||||
|
new ApiResource
|
||||||
|
{
|
||||||
|
Name = apiName,
|
||||||
|
Description = "My API",
|
||||||
|
Enabled = true,
|
||||||
|
DisplayName = "test",
|
||||||
|
Scopes = new List<Scope>()
|
||||||
|
{
|
||||||
|
new Scope("api"),
|
||||||
|
new Scope("api.readOnly"),
|
||||||
|
new Scope("openid"),
|
||||||
|
new Scope("offline_access"),
|
||||||
|
},
|
||||||
|
ApiSecrets = new List<Secret>()
|
||||||
|
{
|
||||||
|
new Secret
|
||||||
|
{
|
||||||
|
Value = "secret".Sha256()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UserClaims = new List<string>()
|
||||||
|
{
|
||||||
|
"CustomerId", "LocationId", "UserType", "UserId", "Role"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
})
|
||||||
|
.AddInMemoryClients(new List<Client>
|
||||||
|
{
|
||||||
|
new Client
|
||||||
|
{
|
||||||
|
ClientId = "client",
|
||||||
|
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
|
||||||
|
ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
|
||||||
|
AllowedScopes = new List<string> { apiName, "api.readOnly", "openid", "offline_access" },
|
||||||
|
AccessTokenType = tokenType,
|
||||||
|
Enabled = true,
|
||||||
|
RequireClientSecret = false,
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.AddTestUsers(users);
|
||||||
|
})
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UseIdentityServer();
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_identityServerBuilder.Start();
|
||||||
|
|
||||||
|
_steps.VerifyIdentiryServerStarted(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -27,7 +27,25 @@ namespace Ocelot.UnitTests.Authorization
|
|||||||
{
|
{
|
||||||
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
||||||
{
|
{
|
||||||
new Claim("UserType", "registered")
|
new Claim("UserType", "registered"),
|
||||||
|
|
||||||
|
}))))
|
||||||
|
.And(x => x.GivenARouteClaimsRequirement(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"UserType", "registered"}
|
||||||
|
}))
|
||||||
|
.When(x => x.WhenICallTheAuthoriser())
|
||||||
|
.Then(x => x.ThenTheUserIsAuthorised())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_authorise_user_multiple_claims_of_same_type()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim("UserType", "guest"),
|
||||||
|
new Claim("UserType", "registered"),
|
||||||
}))))
|
}))))
|
||||||
.And(x => x.GivenARouteClaimsRequirement(new Dictionary<string, string>
|
.And(x => x.GivenARouteClaimsRequirement(new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user