Java Microservices with Spring Cloud Config and JHipster

Java Microservices with Spring Cloud Config and JHipster

This tutorial shows you how to build a microservices architecture with Spring Boot and Spring Cloud Config using JHipster.

Raul Rotundo

Hi Matt,

I have some problems with @PreAuthorize annotation using keycloak. I cloned your repo and after you added to any controller resource the annotation, for example:


@PreAuthorize(“hasRole(”" + AuthoritiesConstants.ADMIN + “”)")

I receive an 403 forbidden error.

Here some logs:


com.okta.developer.store.repository.CustomAuditEventRepository.add() with argument[s] = [AuditEvent [timestamp=2019-05-24T16:01:34.758324Z, principal=4c973896-5761-41fc-8217-07c5d13a004b, type=AUTHENTICATION_SUCCESS, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails@ffffa64e: RemoteIpAddress: 172.18.0.5; SessionId: null}]]


com.okta.developer.store.repository.CustomAuditEventRepository.add() with argument[s] = [AuditEvent [timestamp=2019-05-24T16:01:34.889309Z, principal=4c973896-5761-41fc-8217-07c5d13a004b, type=AUTHORIZATION_FAILURE, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails@ffffa64e: RemoteIpAddress: 172.18.0.5; SessionId: null, type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]]

This means the user authentication was successfully but after that, I get the authorization failure.

This could be for a misconfiguration of the “internal” client (jhipster-realm.json)? I don’t know.

I appreciate your help.

Thanks

Brian Demers

Hey Raul!

One of the things I do to help troubleshoot this type of issue is I comment out the @PreAuthorize annotation, and inject the JwtAuthenticationToken (or similar Authentication). From there you can set a breakpoint or log the results of JwtAuthenticationToken.getAuthorities() You can also check the getTokenAttributes() to make sure your groups claim is set.

Let us know what you find!

Raul Rotundo

Hi Brian!

Thanks for your response, this is what I got:

jwtAuthenticationToken:


jwtAuthenticationToken: org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken@3d4af8fe: Principal: org.springframework.security.oauth2.jwt.Jwt@f47b3487; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffffe21a: RemoteIpAddress: 172.18.0.7; SessionId: null; Granted Authorities: SCOPE_openid, SCOPE_jhipster, SCOPE_email, SCOPE_offline_access, SCOPE_profile, SCOPE_address, SCOPE_phone

jwtAuthenticationToken.getTokenAttributes():


{sub=4c973896-5761-41fc-8217-07c5d13a004b, resource_access={“account”:{“roles”:[“manage-account”,“manage-account-links”,“view-profile”]}}, email_verified=true, address={}, allowed-origins=[“http://localhost:8080/","http://localhost:8100/”,“http://127.0.0.1:8761/","http://localhost:9000/”], iss=http://keycloak:9080/auth/realms/jhipster, typ=Bearer, preferred_username=admin, given_name=Admin, aud=[account], acr=0, nbf=1970-01-01T00:00:00Z, realm_access={“roles”:[“ROLE_USER”,“offline_access”,“ROLE_ADMIN”,“uma_authorization”]}, azp=web_app, auth_time=1558781630, scope=openid jhipster email offline_access profile address phone, name=Admin Administrator, exp=2019-05-25T11:06:17Z, session_state=160e0882-155f-40dc-bdf8-46d0f846738c, iat=2019-05-25T11:01:17Z, family_name=Administrator, jti=5d413238-1859-4d3b-89fc-62581205dd33, email=admin@localhost}

jwtAuthenticationToken.getName() (User ID):


4c973896-5761-41fc-8217-07c5d13a004b

As you can see on jwtAuthenticationToken.getTokenAttributes() logs, there is no “groups” claim set, how can I do this on keycloak and okta?

Another question is why this is not working if I can see “Roles” claims and it’s also present ROLE_ADMIN on that?

By the way, this is what I got when I generated a jhipster microservices application (Registry, Gateway, a Microservice, Keycloak, etc…) using Jhipster version 6.0.1 without any modification, same way Matt did in order to create this post.

Regards,

Raul

Jose Diaz diaz

I am stopped in this part Create Groups and Add Them as Claims to the ID Token . Maybe some video is better, because I am not familiar with okta.

Matt Raible

Here’s a screencast I did last month that shows how to setup Okta to work with JHipster: https://youtu.be/Ktnvqoouulg.

Brian Demers

Hey Raul!
Follow these same steps, but instead of an “ID Token” select "Access Token"
https://developer.okta.com/…

That will include the groups claim in the access token that is passed downstream to your service.

keeps

I look in your repo and compare the code that i generated. it look a bit difference (e.g. your jhipster-registry:v5.0.0 and mine is 4.1.1) even-though my code just generated today using 6.0.1 generator. The app.jh is the same. Did i miss any steps?

Raul Rotundo

Brian do you know how to set the “groups” claim using keycloak? I’m doing this using jhipster and keycloak with data generated by default and I can’t figure it out how to add the groups claim to the token and be able to resolve the @PreAuthorize problem that is how this start.

I saw an open ticket in jhipster generator that may be related to this. https://github.com/jhipster…

Raul Rotundo

I resolved how to set “groups” claims to keycloak, basically what I did was go to Clients > internal > Mappers and add a groups claim by “Add Builtin” option.

Now it’s present within the token


{sub=4c973896-5761-41fc-8217-07c5d13a004b, resource_access={“account”:{“roles”:[“manage-account”,“manage-account-links”,“view-profile”]}}, allowed-origins=[“http://localhost:8080/","http://localhost:8100/”,“http://127.0.0.1:8761/","http://localhost:9000/”], iss=http://keycloak:9080/auth/realms/jhipster, typ=Bearer, preferred_username=admin, acr=1, realm_access={“roles”:[“ROLE_USER”,“offline_access”,“ROLE_ADMIN”,“uma_authorization”]}, azp=web_app, auth_time=1559060498, scope=openid jhipster email offline_access profile address phone, exp=2019-05-28T16:26:38Z, session_state=93f33746-744c-4eaa-8ddb-bbb5ad6a9fa0, iat=2019-05-28T16:21:38Z, jti=acb2799e-8e0b-4583-a378-52ac3b2f2f4f, email=admin@localhost, email_verified=true, address={}, groups=[“ROLE_USER”,“offline_access”,“ROLE_ADMIN”,“uma_authorization”], given_name=Admin, aud=[account], nbf=1970-01-01T00:00:00Z, name=Admin Administrator, family_name=Administrator}

However, this change does not fix the issue related with @PreAuthorize annotation. Still having AUTHORIZATION_FAILURE.

Brian Demers

I’m not sure on the keycloak specifics, but assuming the access token is a JWT, with claims, you can add a JwtAuthenticationConverter component, simialr to what we do for Okta: https://github.com/okta/okt…

Let us know how you make out!

Raul Rotundo

Hi Brian, what I did to fix my @PreAuthorize problem was add a custom @PreAuthorize validation something like this article describe: https://tuhrig.de/expressio… and then, mapping claims and set a boolean function to see if the role if present within realms_access.roles or not. Maybe this solutions is not a good approach but at least resolved my main problem with Authorisations. Regards

Matt Raible

I’m not sure why they would be different. If you run jhipster --version, does it say “6.0.1”?

Biswadeep Basu

Hi Matt,

Awesome tutorial! :slight_smile:

Few queries, In the section where you mention

"Give your app a memorable name, add http://localhost:8080/login/oauth2/code/okta as a Login redirect"

It does not work if I specify this as login url (Gives me a 404 when trying to login through the gateway app). Instead if I give the below login url it works.

http://localhost:8080/login/oauth2/code/oidc

Also, I see some strange error like “Request method ‘POST’ not supported” when using the app for the first time. Once restarted using decoker-compose restart, apis works fine.

Additionally, every api (blog or store) for the first time throws a 504 time out of Hystrix. Any global config to set a higher time out value?

Matt Raible

Hello Biswadeep,

You are correct. There is a typo in this tutorial. The correct URL is “http://localhost:8080/login/oauth2/code/oidc”. I’m not sure how to fix the POST or 504 errors. I have seen them myself. I’ve opened an issue on the JHipster project to investigate.

Azeem Mohammed

Hi Matt,

Thanks for your tutorial. I have question. does jhipster supports spring Cloud gateway?

Matt Raible

No. Not yet. I hope to help integrate it soon though! It’s necessary for a full reactive stack.

Hamzah Qureshi

Hi Matt, Thanks for the tutorial.
I have followed it as it is except instead of using docker i am deploying everything locally. The problem i am facing is that, the users created in jhi-user table after logging in from okta credentials, those users are not assigned any roles. Due to which when i try to access any entity, i get “access denied” error. What could be the issue ?

Matt Raible

You have to create ROLE_ADMIN and ROLE_USER groups on Okta, and then add a “groups” claim to your ID token. Then it will be synced by the UserService#syncUserWithIdP() when you log in.

mxu

A bit off the topic, how much memory do I need to run the “docker-compose up”. It seems the blog and store apps could not start due to some memory or CPU constraints. I can see the Kibana (port 5601), port 8671 jhipster console and port 9080 Keycloak. But nothing on port 8080, 8081 and 8082. I am on a late 2012 model Macbook with 8gb memory.