-
-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OIDC support for Microservices architecture #6435
OIDC support for Microservices architecture #6435
Conversation
As @mraible explained #6435 , I started a microservices support for Oauth2. So far, I succeed to generates a Gateway with OAuth2Sso enabled (redirects the user to Keycloak for authentication and successfully load principal and authorities) and ResourceServer (API's gateways's endpoints are accessible via a http client js or curl or whatever). In order combine both features I had to define 2 mutually excluding configurations). The gateway also acts as a token relay to provide jwt to the backend microservices. In monolith applications when the authenticationType is oauth2 a set of user management files was generated. Currently in a microservice architecture I skip the user related files (everything is delagated to the IdP). Regarding the code itself, it does work and the existing generator-jhipster test work. I didn't added new ones so far. Regarding the generated apps I didn't run the tests suite or generate all the combination. |
Awesome! We need to find a solution for the Swagger doc, but this is a minor point compared to the rest (for a first release, that's not a blocker issue) |
If we follow UAA pattern, none of te gateway or services components expose user-management endpoint (/account, /register, etc). For me there is 3 options:
At the moment I think option#3 it's the cleaner from an architecture stand point, it's coherent with the gateway orchestration responsability... but it adds responsibility ro this component. What do you think? |
-> outside of those comments, how can I help you? |
@danielpetisme not entirely sure if I understand but here are some thoughts. Option 2 and/or 3 sound best to me. Do you have to choose? Here's an example gateway configuration where it uses zuul AND security.oauth2.resource.userInfoUri. |
@sdoxsee you're right I can actually use both approaches but I'm not sure it's consistent That means that I could use to Zuul to map some urls. For instance a Zuul rule to map /api/account to I'm not a Zuul expert so feel free to correct me. NOTE: Another option could simply be to say that User management isn't a Jhipster concern anymore and it's up to the dev to integrate it's oauth provider into the generated app. It's not the proposition I prefer but it's a pramatic (radical) option. |
@jdubois
Regarding the Travis CI status, I don't understand the issues (it failed on I'm currently running the test suite... we'll see EDIT |
I'd say that with oidc, user management is not longer a jhipster concern since many oidc providers also have user management but feel free to push back on that...as long as jhipster can handle the role and permissions from the IdP. |
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) | ||
public class MicroserviceSecurityConfiguration extends ResourceServerConfigurerAdapter { | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extra line break.
} | ||
<%_ } _%> | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extra line break.
.and() | ||
.sessionManagement() | ||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) | ||
.and() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend out-denting the .and
s in this code block, like https://github.com/jhipster/generator-jhipster/blob/master/generators/server/templates/src/main/java/package/config/_SecurityConfiguration.java#L191.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@danielpetisme After modifying application.yml
to have the following, I'm able to login with a monolith again. This is probably why Travis doesn't pass.
oauth2:
issuer: http://localhost:9080/auth/realms/jhipster
security:
basic:
enabled: false
oauth2:
client:
accessTokenUri: ${oauth2.issuer}/protocol/openid-connect/token
userAuthorizationUri: ${oauth2.issuer}/protocol/openid-connect/auth
clientId: web_app
clientSecret: web_app
clientAuthenticationScheme: form
scope: openid profile email
resource:
userInfoUri: ${oauth2.issuer}/protocol/openid-connect/userinfo
tokenInfoUri: ${oauth2.issuer}/protocol/openid-connect/token/introspectr
preferTokenInfo: false
Also, this PR seems to be missing the following files for a monolith. They should be copied when selecting oauth2
.
generators/server/prompts.js
Outdated
this.skipUserManagement = true; | ||
} | ||
|
||
if (this.applicationType === 'uaa') { | ||
this.authenticationType = 'uaa'; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extra line break.
resource: | ||
userInfoUri: ${oauth2.issuer}/protocol/openid-connect/userinfo | ||
tokenInfoUri: ${oauth2.issuer}/protocol/openid-connect/token/introspectr | ||
preferTokenInfo: false | ||
jwt: | ||
keyUri: ${oauth2.issuer} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These lines aren't needed for a monolith, so should only be included for microservice architecture.
oauth2: | ||
client: | ||
accessTokenUri: ${oauth2.issuer}/protocol/openid-connect/token | ||
userAuthorizationUri: ${oauth2.issuer}/protocol/openid-connect/auth | ||
<%_ if (applicationType === 'gateway') { _%> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clientId
, clientSecret
, clientAuthenticationScheme
, and scope
should also be included for a monolith, but tokenName
is not needed.
oauth2: | ||
issuer: http://localhost:9080/auth/realms/jhipster | ||
principal-attribute: preferred_username | ||
authorities-attribute: roles |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
principal-attribute
and authorities-attribute
not needed for monolith.
clientSecret: internal | ||
authenticationScheme: header | ||
clientAuthenticationScheme: header | ||
<%_ } _%> | ||
resource: | ||
userInfoUri: ${oauth2.issuer}/protocol/openid-connect/userinfo | ||
tokenInfoUri: ${oauth2.issuer}/protocol/openid-connect/token/introspectr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to http://localhost:9080/auth/realms/jhipster/.well-known/openid-configuration, the tokenInfoUri
should be http://localhost:9080/auth/realms/jhipster/protocol/openid-connect/token/introspect
. This is a mistake I made in my PR. However,, it doesn't seem to matter what the value is.
@@ -360,6 +360,7 @@ dependencies { | |||
<%_ } _%> | |||
<%_ if (authenticationType === 'oauth2') { _%> | |||
compile "org.springframework.security.oauth:spring-security-oauth2:${spring_security_oauth2_version}" | |||
compile "org.springframework.security:spring-security-jwt" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't needed when using OAuth 2.0 and a monolith.
generators/server/templates/_pom.xml
Outdated
<dependency> | ||
<groupId>org.springframework.security</groupId> | ||
<artifactId>spring-security-jwt</artifactId> | ||
</dependency> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't needed when using OAuth 2.0 and a monolith.
The test about oauth2 are not failing anymore now it's eureka. It's strange because it fails on things like:
I'm not 100% sure it's related to the code itself. |
Just noticed a regression. When selecting |
More testing... when creating a microservice gateway, shouldn't we prompt for JHipster Registry vs. Consul? The answers don't seem to line up:
|
@mraible maybe you're not on the right branch, or had an issue with I need all this for my current client: I'm going to do a quick review |
|
@jdubois What I propose in a first release is to remove all the user-management related files (as proposed by @sdoxsee). That means no more account settings page, account creation or users settings and user. The end user will have to go to the IdP to create an account or deal with his settings. In a second shot, we can work on a Jhipster support of the account/users UI + IdP API orchestration in the gateway. What do you think guys? |
@danielpetisme yes for me all the user account management is handled by Keycloak/Okta, that's one of the main points of using this method. Like we do in JHipster UAA. So yes you should "skip user management". |
The uaa deals with user management but since it's a jhipster app it's registered in the registry and accessible via the gateaway and visible from the gateway UI. I'll update the code tonight to not generate the user related files. |
Oh yes, let me detail:
Now for Keycloak only, as it can be used as a Docker image:
|
I agree that users should be created elsewhere. However, in the monolith implementation, I keep some of the user-related classes. My reason is so there can be a The JHipster app is not allowed to update the user, but UserResource/Repository can be used to query the user. FWIW, I've sent this code to the Spring Security folks for a code review. |
I've reviewed the code in more detail, and my main issue is this configuration from @mraible
This configuration is not type safe, and to be consistent with the rest of the code: it should be stored in https://github.com/jhipster/jhipster/blob/master/src/main/java/io/github/jhipster/config/JHipsterProperties.java using a |
I just released https://github.com/jhipster/jhipster/releases/tag/v1.1.12 that includes the new OAuth2 configuration (see jhipster/jhipster@6ff3a22 ) -> you need to migrate the configuration to the new |
@jdubois |
Yes Matt I understand that - it's a specific case we haven't had before.
But it took me some time to understand: if it's coded and documented like
the rest, and uses a 'jhipster' prefix, I think it would be easier to
understand.
You would also have automatic completion with Idea: when this doesn't work
I'm always looking at what's wrong.
Le 10 oct. 2017 17:59, "Matt Raible" <notifications@github.com> a écrit :
… @jdubois <https://github.com/jdubois> oauth2.issuer is not used by any
code, it's only a shortcut for the other OAuth-related properties that
Spring Security OAuth uses. The other two properties (principal-attribute
and authorities-attribute) are only used by the microservices code at the
moment.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#6435 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AATVo0EnYKPu9PP_tsHwHY6M9JgdaTlSks5sq5R4gaJpZM4Po-8f>
.
|
@jdubois @mraible I've mixed feelings for. Right now If we plan to pilot the IdP provider (registering for instance) from JHipster code, then this variable could be useful but it will raise more issues (It requires an implementation per provider). Regarding the The OIDC monolith and microservices implementation are not 100% aligned but for the sake of speed I propose to treat this point as a dedicated issue. @mraible sounds good to you if we stay as-is in a first release? |
yes this is just a variable used 4 times @danielpetisme - could we just remove it? And then probably just copy/paste it, that's OK in the YAML file (and not really our fault, this is just the Spring Security OAuth config that works this way). If that's fine, then I'll remove my config in the jhipster/jhipster library. |
+1 for me |
@jdubois If we move it, we'll need to change _app.yml from:
To:
We might need to update some other documentation too. |
@danielpetisme Can you please provide the steps you're using the ensure this PR works? I want to compare your methodology with the one I'm using. Here's what I expect to be able to do:
I think it should also be possible to use the docker-compose and kubernetes sub-generators to create a system that'll start all of the above services. |
@mraible Indeed is confusing to have a |
@jdubois How did you build and deploy the |
I could skip the loading of |
@danielpetisme I created #6510 against master to remove |
@danielpetisme I removed the old "oauth" code, and as we said we wouldn't use this property (as it's copy/pasted), there is no specific JHipster configuration here - that's why you don't see anything. If you want to use the lib, just clone its repo, and you can do a |
@mraible oh I didn't see you were syncing users from OIDC:
|
|
There's a blocking bug at the moment: when you re-generate an app, it changes in your |
Oops.... So sorry everyone, I merged this by mistake!!! I'm doing a JHipster training and I was trying to show a few tricks, and of course I messed up badly :-( |
I fixed the bug you mentioned @jdubois + I reuse @mraible user sync as-is for microservice architecture (only for gateways). I think it's good enough for a first release. Regarding the anticipated merge. Do you want me to create a new PR? I can create one to fix the bug and another for the user sync if you want. |
Yes please ... really sorry |
1 or 2 pr ? |
Oh sorry - the easiest for you, so 1 I guess |
I'm using generator v4.9.0 but I don't see keycloak.yml created under docker directory. |
@adnansenyurt this isn't released yet, this why this ticket is not yet linked to a release version. You should use the |
Please make sure the below checklist is followed for Pull Requests.
Travis tests are green
Tests are added where necessary
Documentation is added/updated where necessary
Coding Rules & Commit Guidelines as per our CONTRIBUTING.md document are followed