-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Allow SSO authentication to provide a user secret #27929
Conversation
ad36b8c
to
3a066e3
Compare
Thanks, @MichaIng! Sorry for the hassle. Do you think you could give me a hand with figuring out why this PR is failing? It's the companion code for the |
3a066e3
to
a246c14
Compare
5588003
to
a2fc512
Compare
06bc829
to
b4af323
Compare
CI is happy now. |
b4af323
to
4940ac9
Compare
* @return string | ||
* @since 23.0.0 | ||
*/ | ||
public function getCurrentUserSecret(): string; |
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.
Would making this nullable make sense? Especially as $password = null;
is the default.
public function getCurrentUserSecret(): string; | |
public function getCurrentUserSecret(): ?string; |
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 think the idea was to explicitly not allow a null value here, so that checks can be omitted when the interface is implemented. Backends then need to always provide a string.
Ref: #27929 (comment)
But I see this is inconsistent with the description "Optionally returns a stable per-user secret.", which just has not been changed when I copy&pasted it from IApacheBackend
(original idea, where it needed to be optional, of course) to its own interface. Shall I replace with:
* Returns a stable per-user secret e.g. used to secure file encryption keys.
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 think I suggested to introduce the non-nullable return value earlier. To me it seems more reasonable as the user secret would be used for the user key encryption where I'd argue that if a backend provides user secrets there should be always one set for the user.
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.
Two comments/issues:
- I've tried the most recent version of this PR with the
IProvideUserSecretBackend
in conjunction with the associated user_saml plugin PR:
support for per-user encryption user_saml#537
.
Since users logging in with this method would be using theuser_saml
backend,lib/private/legacy/OC_User.php:177
never gets executed. Therefore, the password is never set. Am I missing something? - With the code from the original PR, there seems to be a problem. After a few minutes,
heartbeat
requests start returning 401 responses. Then, anygetstoragestats
request triggers a page refresh after a 401 response because the session is no longer valid. I have yet to determine what is causing the session to fail, but it is a problem.
Any thoughts? I have a local Keycloak -> NC dev setup working, and I'm happy to test.
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.
Without a password,
getCurrentUserSecret()
will return null. So, this suggested change should either be reversed (probably the recommended solution) or a try/catch should be added
Is it possible that user_saml
"provides" the IProvideUserSecretBackend
only when a user secret is actually set? In theory this would then reduce some overhead, when the backend is used without it and would make allowing/checking for null
obsolete, right? But I clearly lack knowledge about theses things, so probably it's nonsense 😄.
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 have a proposal to get us unstuck here. How about we make IProvideUserSecretBackend::getCurrentUserSecret()
nullable (or conditionally implementing IProvideUserSecretBackend is fine too -- anything that gets us unstuck...), but then do the following:
$password = null;
if ($backend instanceof \OCP\Authentication\IProvideUserSecretBackend) {
$password = $backend->getCurrentUserSecret();
}
if ($password !== null) {
$userSession->createSessionToken($request, $uid, $uid, $password);
} else {
$userSession->createSessionToken($request, $uid, $uid);
}
This would allow us to disentangle the two problems, preserve the identical behavior for the non-userSecret case and let createSessionToken
decide what to do when there is no password. This solution would also be more robust, as it removes that dependency on the decision if token passwords are nullable or not and allows us to define an interface that is independent of that.
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.
Isn't it exactly the same outcome whether passing $password = null
or no argument at all? The createSessionToken
has it's fourth argument null
in both cases, isn't it?
The main question is indeed whether we want to be more explicit and force usage of a password when the backend is implemented or whether we want to allow implementing the backend without the need to provide a password. Generally I'm fans of being more explicit, but I understand that it may make the backend implementation more complicated.
I think it is agreed that we can or even should merge this PR first, before doing so at the backend, especially since the interfaces are defined here, so the above is really the last open question. I think we need someone who is more in charge to simply do a decision and we'll be able to deal with the result. But we need to get unstuck 😄.
3bd722b
to
32aafe6
Compare
32aafe6
to
a26e451
Compare
a26e451
to
988d080
Compare
988d080
to
5dd02c5
Compare
5dd02c5
to
1e7c0ca
Compare
1e7c0ca
to
9a3e63b
Compare
Hi, what is the status of this PR? It seems to me that we have managed to have fairly non-intrusive changes here, that will not change or break any existing interface, but allows us to continue with the saml side of things. Are there any remaining objections to address before inclusion, @blizzz since you pushed the milestone? |
9a3e63b
to
ba34c32
Compare
Rebased and resolved conflict. We need someone to decide whether the API function should be allowed to return null or not (see discussion in code review). |
Two things happened:
In summary, the people behind this PR agree on the api, the original author agrees, the api works for the intended usecase and this PR is not blocked by any external decision. So I think we took that decision that you are talking about. If not, please let me know who can take this decision. |
So we just need another approval. The failing S3 checks are unrelated, fail randomly, I'll try to resolve with a rebase before merging. |
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.
Looks good
Implementing PR #24837 from immerda Signed-off-by: MichaIng <[email protected]>
ba34c32
to
21b3e87
Compare
Drone failure is unrelated, but I cannot merge due to it. Please someone do, so work on nextcloud/user_saml#537 can finally go on 🙂. |
Implementing PR #24837 from immerda
As of my failed attempt to fix #27909 😄.