-
Notifications
You must be signed in to change notification settings - Fork 554
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
feat: implement authentication layer #18428
Conversation
10c26b6
to
bbe8387
Compare
.../auth-starter/src/main/java/io/camunda/identity/authentication/config/WebSecurityConfig.java
Fixed
Show fixed
Hide fixed
Tasklist Test Results549 tests 544 ✅ 1h 31m 52s ⏱️ Results for commit bf50761. ♻️ This comment has been updated with latest results. |
Operate Test Results265 tests 264 ✅ 34s ⏱️ Results for commit 3fa08d5. ♻️ This comment has been updated with latest results. |
3519590
to
8121bb7
Compare
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.
The structure looks good to me, I have a few suggestions that you can find in following comments.
@Profile("identity-oidc-auth") | ||
public class OidcCurrentUserService implements CurrentUserService { | ||
@Override | ||
public CamundaUser getCurrentUser() { |
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'm thinking if we need a separate implementation for oidc, as the authorities can be retrieved from authentication object (it would be an instance of OAuth2AuthenticationToken). The only difference is using authentication.name which extracted from claims["name"] instead of principal.getPreferredUsername which filled from claims["preferred_username"].
final OidcUser oidcUser = super.loadUser(userRequest); | ||
final UserDetails details = userDetailsManager.loadUserByUsername(oidcUser.getName()); | ||
if (details != null) { | ||
return new CamundaOidcUser( |
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.
Intellij suggests to use map(GrantedAuthority.class::cast)
} | ||
|
||
@Override | ||
protected List<GrantedAuthority> loadUserAuthorities(final String username) { |
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.
Do we need this override for the current issue?
if it's required I suggest to give a try to override JdbcDaoImpl#addCustomAuthorities.
but if not, it's better to remove it for now and make it working later with the tasks related to add role/permission to identity.
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.
We don't need it (I just checked) so I'm removing it :)
Operate Opensearch ITs Results182 tests 182 ✅ 54s ⏱️ Results for commit bf50761. ♻️ This comment has been updated with latest results. |
Operate Integration Tests Results523 tests 521 ✅ 8m 20s ⏱️ Results for commit bf50761. ♻️ This comment has been updated with latest results. |
Operate Unit Tests Results275 tests 274 ✅ 6m 21s ⏱️ Results for commit bf50761. ♻️ This comment has been updated with latest results. |
4d4d042
to
2219be1
Compare
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.
Thank you for the code. The current combination of basic auth (local user management) and OIDC is confusing since it is not in the scope of the issue, so I recommend removing OIDC here.
...tarter/src/main/java/io/camunda/identity/authentication/basic/CamundaCurrentUserService.java
Outdated
Show resolved
Hide resolved
...tarter/src/main/java/io/camunda/identity/authentication/basic/CamundaCurrentUserService.java
Outdated
Show resolved
Hide resolved
...h-starter/src/main/java/io/camunda/identity/authentication/basic/CamundaOidcUserService.java
Outdated
Show resolved
Hide resolved
...h-starter/src/main/java/io/camunda/identity/authentication/basic/CamundaOidcUserService.java
Outdated
Show resolved
Hide resolved
...h-starter/src/main/java/io/camunda/identity/authentication/basic/CamundaOidcUserService.java
Outdated
Show resolved
Hide resolved
@@ -5,11 +5,10 @@ | |||
* Licensed under the Camunda License 1.0. You may not use this file | |||
* except in compliance with the Camunda License 1.0. | |||
*/ | |||
package io.camunda.identity.usermanagement; | |||
package io.camunda.identity.authentication; |
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.
Do we need identity
in the folder structure / class names? This way we have identity
and authentication
as (sub)domains. If we consider identity
as the top level domain here, then it would make sense to split the internals in authentication
and authorization
. Otherwise we could just have a top level domain authentication
and omit identity
. What do you think?
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.
Initially had included identity
because its our realm and Identity is still a component in the stack in the same way we have io.camunda.operate...
etc so I'd prefer to keep it, but I can see how we could remove this and have a flat level of io.camunda.authentication
. Ultimately I don't feel strongly either way so I will change it if you have stronger feelings than me :D
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.
and Identity is still a component
That is also a reason to not use identity
here, so it is not confused with the application/component in the end. On a scale of 1-10 I am at about 6.5 that we should not use identity here, but just keep it simple as io.camunda.authentication
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.
Ok, I've changed it to io.camunda.authentication
...ain/java/io/camunda/identity/authentication/handler/CamundaAuthenticationFailureHandler.java
Outdated
Show resolved
Hide resolved
...ain/java/io/camunda/identity/authentication/handler/CamundaAuthenticationFailureHandler.java
Outdated
Show resolved
Hide resolved
* Licensed under the Camunda License 1.0. You may not use this file | ||
* except in compliance with the Camunda License 1.0. | ||
*/ | ||
package io.camunda.identity.record; |
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 suggest structuring the code by the domain instead of class type, so for example having a users
directory with all user related records and services instead of service
and records
directories. This structure should be more robust as the code grows. In Identity it became challenging to name classes in a single directory - especially records as these could include entities but also request objects and DTOs. What do you think?
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.
Sounds good, I've updated this structure now
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.
The idea of naming the packages with subdomain sounds good but I have some concerns here regarding how to find a subdomain that contains all relevant stuffs. For example when we named this package as user, then when we want to add group dtos we need to add a new package with one class only that's not looks nice, also for user roles and group roles and group users how we can proceed with this style?
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.
An example structure for roles: everything related to roles would live in a roles
directory. This could be a subdirectory of users
or on the same level and would contain all DTOs and services to retrieve/manage roles. Working with subdirectories can give more granularity and a structure similar to api endpoints while having these on the same level should be easier for reusable parts like.
An example why I think that structuring by domain is a good idea is multitenancy. We would have a directory tenants
containing all controllers, services, records, DTOs etc... and all of these can be annotated to only be included if multitenancy is activated. Otherwise the multitenancy annotation would be present on different classes in different directories and would be harder to follow
@@ -0,0 +1,10 @@ | |||
services: |
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.
It looks like this file is only for testing, but otherwise I can't see any instructions on how to use it. Should we remove it here and rather add it as part of automatic test coverage?
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 file should be removed, right?
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.
Ugh yea, sorry I removed it and then added it back in for local testing 🤦🏻
|
||
@Bean | ||
@Primary | ||
@Profile("auth-basic") |
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.
Do we need to have this here as well as on the class level above? 🤔
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.
Good spot, that was left over from when we had multiple applicable beans in here, I'll remove
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 only have one concern regarding the package names but it's not necessary to be addressed in this PR. Otherwise it looks good to me.
return httpSecurity | ||
.authorizeHttpRequests( | ||
(authorizeHttpRequests) -> | ||
authorizeHttpRequests | ||
.requestMatchers(UNAUTHENTICATED_PATHS) | ||
.permitAll() | ||
.anyRequest() | ||
.authenticated()) | ||
.headers( | ||
(headers) -> | ||
headers.httpStrictTransportSecurity( | ||
(httpStrictTransportSecurity) -> | ||
httpStrictTransportSecurity | ||
.includeSubDomains(true) | ||
.maxAgeInSeconds(63072000) | ||
.preload(true))) | ||
.exceptionHandling( | ||
(exceptionHandling) -> exceptionHandling.accessDeniedHandler(authFailureHandler)) | ||
.csrf(AbstractHttpConfigurer::disable) |
Check failure
Code scanning / CodeQL
Disabled Spring CSRF protection High
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.
LGTM 🚀
Closes https://github.com/camunda-cloud/identity/issues/2804
Description
This PR achieves a couple of tasks out of necessity so its a little larger than I'd often like, still, here goes:
auth-starter
module under Identity that provides a centralised configuration for auth related classesbackend
code with the new auth layer by way of aidentity-common
modulepostgres
,h2
Things that I want to highlight:
Camunda
where there are classes that we extend from Spring so that its obvious its our code/dist
approach and I've also tried to align the configurations