Comments (6)
Short answer: @WithMockKeycloakAuth({"ADMINISTRATOR", "DRIVER"})
just above your @Test
as demonstrated in samples and on stackoverflow answers.
Long answer: authorities (in Spring-security world a role is an authority prefixed with ROLE_
) are populated from a JWT by an authorities converter. Keycloak get authorities from different claims to retrieve realm roles and client roles. You need to explore Keycloak sources (starting from KeycloakWebSecurityConfigurerAdapter
) if you are interested in figuring out how this is exactly done.
In your sample, you are setting roles in a claim named resource_access.ace-ella-ecosystem.roles
(yes, a claim name is a JSON string and yes, JSON string can contain dots) when keycloak expects a roles
string-array claim inside a ace-ella-ecosystem
claim-set itself inside a resource_access
claim-set. As this is pretty cumbersome to declare with @ClaimSet
and @StringArrayClaim
(not @StringClaim
as you did), I recently created a @JsonObjectClaim
that works close to what you wrote. But the simple sollution to set authorities is clearly to use authorities
property on @WithMockKeycloakAuth
.
from spring-addons.
@ch4mpy I still get 403 even with your example.
The test:
@Test
@WithMockKeycloakAuth({"ADMINISTRATOR", "DRIVER"})
void exampleTest() throws Exception {
var uri = URI.create("/v1/support");
mockMvc.perform(
MockMvcRequestBuilders.post(uri)
)
.andExpect(MockMvcResultMatchers.status().isOk());
}
However since we are using client roles, we have this in configuration:
keycloak:
auth-server-url: ${KEYCLOAK_AUTH_SERVER_URL}
realm: ${KEYCLOAK_REALM}
resource: ${KEYCLOAK_RESOURCE}
public-client: true
ssl-required: external
bearer-only: true
use-resource-role-mappings: true
from spring-addons.
Had missed
simpleAuthorityMapper.setPrefix("ROLE_");
Have you tried @WithMockKeycloakAuth({"ROLE_ADMINISTRATOR", "ROLE_DRIVER"})
?
from spring-addons.
Thanks, that works. I haven't though about it, because token has roles without prefix. I can't believe solution was this simple. 😄
Anyways everything works, thank you very much, you helped a lot. 🍺
from spring-addons.
Hi, @ch4mpy me again :D
I have slightly more complicated use case now, I need to check role inside some service class and I do that like this:
var allowedRoles = getAllowedRoles().stream()
.map(UserRole::toString)
.collect(Collectors.toSet());
var userRoles = accessToken
.getResourceAccess(keycloakResource)
.getRoles();
However when this code runs inside test, I get following exception:
Body = {"error_code":null,"error_description":null,"exception_class":"java.lang.NullPointerException","exception_message":"Cannot invoke \"org.keycloak.representations.AccessToken$Access.getRoles()\" because the return value of \"org.keycloak.representations.AccessToken.getResourceAccess(String)\" is null"}
I tried following your advice from first message to this question (about nesting claims resource_access -> resource_id -> roles), however I can't seem to understand that approach nor how to nest them. You mentioned something about json object claim, so maybe that is the right way, but if you could tell me something more or just point me in right direction I would apreciate it.
Thanks
from spring-addons.
If you want a RessourceAccess to be be populated in your tests, you just need to populate it with something like:
@WithMockKeycloakAuth(accessToken = @KeycloakAccessToken(resourceAccess = @KeycloakResourceAccess(resourceId = "demo", access = @KeycloakAccess(roles = {"machin", "truc"}))))
Setting authorities with @WithMockKeycloakAuth
can't populate claims. Keycloak-spring adapter retrieves authorities from several places: at least "client roles" (by default resource_access.{clientId}.roles
) and "realm roles" (by default realm_access.roles
).
I write "by default", because this is configurable with mappers and can actually be set to about anything.
I have a strong recomandation for you: use direct claim access for stuff that are neither authorities nor standard OpenID claims (subject, preferredUserName, etc.).
The mapping from claims to authorities should be made in spring security conf.
Access to authorities in your application code should be done exclusively with KeycloakAuthenticationToken::getAuthorities
.
=> Read Keycloak doc to figure out how to map your Keycloak "roles" claims to Spring "authorities" and then use:
keycloakAuthenticationToken.getAuthorities()
in your application code (that's what do implicitely@PreAuthorise(hasAnyAuthority(...))
and@PreAuthorise(hasAnyRole(...))
)@WithMockKeycloakAuth(authorities= {...})
in your tests
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.