[OID4VCI] Revisit and fix OAuthClient.authorizationRequest()#45985
[OID4VCI] Revisit and fix OAuthClient.authorizationRequest()#45985tdiesler wants to merge 1 commit intokeycloak:mainfrom
Conversation
502ba59 to
28eb777
Compare
59df973 to
6fd3612
Compare
Unreported flaky test detectedIf the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR. org.keycloak.testsuite.model.infinispan.EmbeddedInfinispanSplitBrainTest#testLocalCacheClearedOnMergeEventKeycloak CI - Store Model Tests |
1fca3ae to
74a8fe3
Compare
98a3e1f to
3c620a1
Compare
|
|
||
| import static org.keycloak.OAuth2Constants.SCOPE_OPENID; | ||
|
|
||
| public class AuthorizationRequestRequest extends AbstractHttpGetRequest<AuthorizationRequestRequest, AuthorizationRequestResponse> { |
There was a problem hiding this comment.
It will be good to avoid introducing another class, but rather would be good to re-use existing LoginUrlBuilder and add support to it for the new parameters like issuer_state and authorization_details . As it will be good to avoid having many duplicated "request" classes in the codebase, which are doing same (or very similar) thing.
Similar point: Would be also good to avoid introducing org.keycloak.protocol.oid4vc.model.AuthorizationRequest in the "services" module. Don't see the need of this class (especially considering that we have already AuthorizationEndpointRequest already in that module, but this is not used by the testsuite and hence is likely out of scope of this PR).
There was a problem hiding this comment.
In #45851 I introduce proper error handling like this ...
public AuthorizationRequestResponse send() {
initRequest();
String endpointUrl = authRequest.toRequestUrl(getEndpoint());
client.driver.navigate().to(endpointUrl);
AuthPageState authPageState = waitForLoginOrError();
switch (authPageState) {
case ERROR_REDIRECT -> {
return new AuthorizationRequestResponse(client);
}
case ERROR_PAGE -> {
Map<String, String> params = new HashMap<>();
params.put("error", "invalid_request");
client.driver.findElements(By.id("kc-error-message")).stream()
.map(d -> d.getText().trim().split("\\n")[0])
.forEach(s -> params.put("error_description", s));
return new AuthorizationRequestResponse(params);
}
// AuthPageState.LOGIN
default -> {
client.fillLoginForm(username, password);
return new AuthorizationRequestResponse(client);
}
}
Currently, we cannot test the error scenario with AuthorizationRequests - it waits for 10sec and then you get a timeout. the error message is lost.
Later still, in #44657 I do a complex IDToken Authorization (when clientId is a DID).
I thought it be good to do this in our oauth.oid4vci() package first, before I change anything in the already existing API that effects everyone. Can please keep this for a little while longer, until we are certain taht we can promote it to the oauth API?
The pattern is this ...
public AuthorizationRequestRequest authorizationRequest() {
return authorizationRequest(new AuthorizationRequest());
}
public AuthorizationRequestRequest authorizationRequest(AuthorizationRequest authRequest) {
return new AuthorizationRequestRequest(client, authRequest);
}
public Oid4vcCredentialRequest credentialRequest() {
return credentialRequest(new CredentialRequest());
}
public Oid4vcCredentialRequest credentialRequest(CredentialRequest credRequest) {
return new Oid4vcCredentialRequest(client, credRequest);
}
i.e. you can either build the request object outside the API (you might also already have it) or populate it through the API. In any case, I would like to have an AuthorizationRequest object so that it can be logged, stored in a context or otherwise processed - it encapsulates what was actually sent when making the request.
AuthorizationRequest supports PKCE and issuer_state and lives in the oid4vci model package. Later when it comes to IDToken Authorization (as required by EBSI) there is other stuff that might need to go in it. Here as well, please can I keep it, until we decide whether to merge oid4vci stuff into the oauth AuthorizationEndpointRequest.
There was a problem hiding this comment.
@tdiesler It will be good to avoid introducing multiple objects for the same thing. The OID4VCI should use LoginUrlBuilder directly instead of introducing it's own object for the same thing. It will be beneficial if LoginUrlBuilder has support for the things like authorization_details anyway.
Currently, we cannot test the error scenario with AuthorizationRequests - it waits for 10sec and then you get a timeout. the error message is lost.
Existing Keycloak tests work in a way that you know if you expect "success" or "error" . For example when you expect error, you may call something like:
errorPage.assertCurrent();
Or eventually, there are similar things to check if the login-page is displayed with some error on the page etc.
I suppose something like public AuthorizationRequestResponse send(expectedOutcome) { should be used instead as the caller should know if it expects "success" page or "error" page.
Later still, in #44657 I do a complex IDToken Authorization (when clientId is a DID).
This is different thing, so might be rather good to introduce related building blocks once/if we add support for this. I see the IDToken authorization handshake rather as out-of-scope of OID4VCI preview feature as it is specific to EBSI and not related to OID4VCI itself.
services/src/main/java/org/keycloak/protocol/oidc/utils/PkceGenerator.java
Show resolved
Hide resolved
5f10ed4 to
3d77d1b
Compare
|
Sending an Authorization request with low level LoginForm API looks like this It is awkward, imho We can preserve the use of LoginForm (i.e. not send an HttpGetRequest from another AuthorizationRequestRequest) and at the time align with the general OAuthClient API like this ... Note, this would ...
Would that be acceptable? |
5d42fb9 to
dabc584
Compare
35cfee7 to
0615a5a
Compare
|
@tdiesler Thanks for the updates. It is probably subjective what is awkward. I am not very sure for a new way with
I will check with the rest of the team as would like more feedback on OAuth client API used in many tests. AFAIK the minimal needed would be to add |
8227f7f to
c192f19
Compare
It allows us to write code like this If you remember, I originally did not wan to have it on In a follow up, I want to add support for improved error handling also preferable for oid4vc only at first. Still later, I want to add IDToken Authorization #44657 We need this abstraction for a number of reasons and ideally we would have it for oid4vc only and later promote it to
Yes, these are not supported nor needed in our current testsuite migration effort
That remains the default.
Yes, I'm sorry that needs to be removed.
Yes, that is already done so How about, I move it back to |
Signed-off-by: Thomas Diesler <tdiesler@ibm.com>
|
This is the right way of doing this: Just do it that way and you're all good? That basically goes hand in hand with OAuth (app sends authz request, the user fills the login form aka authenticates, and you move on with oauth stuff). User may already be authenticated, may not use password only, may need to have some required actions, etc. That is basically the reason it is done the way it is currently. |
closes #45979