Comments (5)
Hi @schmitzhermes and thank you for this detailed issue report.
You are right, it seems that resource access mapping is missing just where you spotted. Will fix asap.
As a side note, you shouldn't define authorities twice. Define it either in authorities
or in private claims.
If your application code just check authorities with standard SpEL (hasAuthority
, hasRole
, etc.), first option is clearly the easiest, less verbose and most readable way (and it already works).
The second option is only necessary if your application code explicitely accesses KeycloakRessourceAccess
, which I personaly discourage as it makes it strongly adherent to Keycloak (migrating to another OIDC authorization server would be painful).
from spring-addons.
There is a pitfall with htis feature: to my understanding, keycloak lib only adds to authorities the roles from a single resource access (the one configured with keycloak.resource
property). This perfectly logical as we are writing and testing the code for this specific resource-server...
I don't have in mind a good way to retrieve such a config property during the tests right now and would rather map all roles from all resource-accesses: if you don't want it in the test security context, don't put it in the test annotation.
But, again, this unit (not integration) testing and roles parsing doesn't involve application authorities mappers (which can do about anything like adding prefix, modifying case, append stuff, or even add or ignore roles) and configuring authorities
with already parsed roles should be the prefered way.
Here is the modified test for the solution I propose:
// @formatter:off
@Test
@WithMockKeycloakAuth(
authorities = {"USER", "AUTHORIZED_PERSONNEL" },
claims = @OpenIdClaims(
sub = "42",
jti = "123-456-789",
nbf = "2020-11-18T20:38:00Z",
sessionState = "987-654-321",
email = "[email protected]",
emailVerified = true,
nickName = "Tonton-Pirate",
preferredUsername = "ch4mpy",
otherClaims = @Claims(jsonObjectClaims = @JsonObjectClaim(name = "foo", value = OTHER_CLAIMS))),
accessToken = @KeycloakAccessToken(
realmAccess = @KeycloakAccess(roles = { "TESTER" }),
authorization = @KeycloakAuthorization(permissions = @KeycloakPermission(rsid = "toto", rsname = "truc", scopes = "abracadabra")),
resourceAccess = {
@KeycloakResourceAccess(resourceId = "resourceA", access = @KeycloakAccess(roles = {"A_TESTER"})),
@KeycloakResourceAccess(resourceId = "resourceB", access = @KeycloakAccess(roles = {"B_TESTER"}))}))
// @formatter:on
public void whenAuthenticatedWithKeycloakAuthenticationTokenThenCanGreet() throws Exception {
api
.get("/greet")
.andExpect(status().isOk())
.andExpect(content().string(startsWith("Hello ch4mpy! You are granted with ")))
.andExpect(content().string(containsString("AUTHORIZED_PERSONNEL")))
.andExpect(content().string(containsString("USER")))
.andExpect(content().string(containsString("TESTER")))
.andExpect(content().string(containsString("A_TESTER")))
.andExpect(content().string(containsString("B_TESTER")));
}
Maybe what you need in your test is somthing like (note the ROLE_
prefix in authorities but not in realm / resource accesses):
// @formatter:off
@Test
@WithMockKeycloakAuth(
authorities = {"ROLE_TESTER", "ROLE_A_TESTER" }, // or {"ROLE_TESTER", "ROLE_B_TESTER" }
claims = @OpenIdClaims(
sub = "42",
jti = "123-456-789",
nbf = "2020-11-18T20:38:00Z",
sessionState = "987-654-321",
email = "[email protected]",
emailVerified = true,
nickName = "Tonton-Pirate",
preferredUsername = "ch4mpy",
otherClaims = @Claims(jsonObjectClaims = @JsonObjectClaim(name = "foo", value = OTHER_CLAIMS))),
accessToken = @KeycloakAccessToken(
realmAccess = @KeycloakAccess(roles = { "TESTER" }),
authorization = @KeycloakAuthorization(permissions = @KeycloakPermission(rsid = "toto", rsname = "truc", scopes = "abracadabra")),
resourceAccess = {
@KeycloakResourceAccess(resourceId = "resourceA", access = @KeycloakAccess(roles = {"A_TESTER"})),
@KeycloakResourceAccess(resourceId = "resourceB", access = @KeycloakAccess(roles = {"B_TESTER"}))}))
// @formatter:on
public void whenAuthenticatedWithKeycloakAuthenticationTokenThenCanGreet() throws Exception {
api
.get("/greet")
.andExpect(status().isOk())
.andExpect(content().string(startsWith("Hello ch4mpy! You are granted with ")))
.andExpect(content().string(containsString("ROLE_TESTER")))
.andExpect(content().string(containsString("ROLE_A_TESTER")))
.andExpect(content().string(containsString("TESTER")))
.andExpect(content().string(containsString("A_TESTER")))
.andExpect(content().string(containsString("B_TESTER")));
}
from spring-addons.
fixed in 3.1.14 (release ongoing). Please, @schmitzhermes close if you can confirm issue is solved.
from spring-addons.
It works just fine - thank you.
One remark: the 3.1.14-jdk1.8
does not seem to be on maven central yet. Is this just a timing thing or do u need to deploy that manually?
from spring-addons.
I can see it on https://repo1.maven.org/maven2/com/c4-soft/springaddons/spring-security-oauth2-addons/
I deploy to sonatype which handles deployment to repo1.maven.org (this rarely takes more than 2 hours)
from spring-addons.
Related Issues (20)
- `authorization-request-params` ignored HOT 1
- POST /logout response Forbidden 403 HOT 9
- Support several JWT authentication converters (or converters with a `@Qualifier` which is not `jwtAuthenticationConverter`)
- Doubled path-prefix by `SpringAddonsServerOAuth2AuthorizationRequestResolver` HOT 1
- Allow anonymous CORS preflight requests (`OPTIONS` requests to a path configured with CORS) HOT 1
- Configuration properties to add parameters to token requests HOT 1
- Spring Starter OICD, Resource Server: Option to disable the default behavior for authorized/protected routes HOT 1
- BFF configuration token is not refreshed HOT 3
- Getting response 401 (Unauthorized) for permit-all requests after update HOT 2
- (Not a bug)Why the custom JwtDecoder bean is useless HOT 2
- `spring-security-oauth2-resource-server`, `spring-security-oauth2-client` and `spring-webflux` should be `optional` dependencies HOT 1
- Support for resource owner password credential flow (ROPC) HOT 1
- Handle CORS Requests with Keycloak's "allowed-origins" claim like the keycloak adapter (now deprecated) HOT 2
- Downstream services times out reading request body when csrf is set to cookie-accessible-from-js HOT 2
- Expand servlet-client tutorial to show calling servlet-resource-server with user that has NICE privileges. HOT 2
- Logout Issue (Invalid CSRF Token) HOT 3
- Import keycloak realms with spring-addons-starters-rest HOT 1
- `@WithOidcLogin` using json file similarly as `@WithJwt` HOT 8
- Need support in resolving 401 Unauthorized Error for Multi Tenant JWT Auth with Resource Server HOT 1
- Invalid SpringAddonsOidcProperties breaks native image HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-addons.