Skip to content

Update ExternalResourceOwnerPasswordCredentialsService.java#14149

Open
ayushjain0702 wants to merge 1 commit into
JanssenProject:mainfrom
ayushjain0702:fix(jans-auth-server)-ROPC-script-custom-error-and-error_description
Open

Update ExternalResourceOwnerPasswordCredentialsService.java#14149
ayushjain0702 wants to merge 1 commit into
JanssenProject:mainfrom
ayushjain0702:fix(jans-auth-server)-ROPC-script-custom-error-and-error_description

Conversation

@ayushjain0702
Copy link
Copy Markdown

@ayushjain0702 ayushjain0702 commented May 25, 2026

Added custom script WebApplicationException handling.

Prepare


Description

Added Custom WebApplicationException handling for ROPC scripts. The current implementation does not allow to customize the error and error_description to be sent to the end user.

Target issue

#14148

closes #14148

Implementation Details

Added Custom WebApplicationException handling for ROPC scripts. The current implementation does not allow to customize the error and error_description to be sent to the end user.


Test and Document the changes

  • Static code analysis has been run locally and issues have been fixed
  • [] Relevant unit and integration tests have been added/updated
  • [] Relevant documentation has been updated if any (i.e. user guides, installation and configuration guides, technical design docs etc)

Please check the below before submitting your PR. The PR will not be merged if there are no commits that start with docs: to indicate documentation changes or if the below checklist is not selected.

  • I confirm that there is no impact on the docs due to the code changes in this PR.

Summary by CodeRabbit

  • Bug Fixes
    • Improved error reporting in authentication script execution, ensuring clients receive proper error responses instead of generic failures and enabling better diagnostic logging.

Review Change Stack

Added custom script WebApplicationException handling. 

Signed-off-by: ayushjain0702 <45758782+ayushjain0702@users.noreply.github.com>
@mo-auto
Copy link
Copy Markdown
Member

mo-auto commented May 25, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

📝 Walkthrough

Walkthrough

This PR modifies error handling in ExternalResourceOwnerPasswordCredentialsService to translate ROPC script exceptions into REST responses. Previously, exceptions were caught and logged silently. Now, WebApplicationException is propagated directly while generic exceptions are wrapped in INTERNAL_SERVER_ERROR responses with ACCESS_DENIED error payloads.

Changes

ROPC Script Error Handling

Layer / File(s) Summary
REST Error Translation for ROPC Script Failures
jans-auth-server/server/src/main/java/io/jans/as/server/service/external/ExternalResourceOwnerPasswordCredentialsService.java
ErrorResponseFactory is injected to construct standardized error responses. Exception handling is rewritten to rethrow WebApplicationException directly (with trace logging), while generic exceptions are logged, persisted via saveScriptError(...), and rethrown as WebApplicationException with an INTERNAL_SERVER_ERROR response containing ACCESS_DENIED error payload.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

kind-bug, comp-jans-auth-server

Suggested reviewers

  • yurem
  • yuriyzz
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is overly vague and generic, using a non-descriptive phrase 'Update ExternalResourceOwnerPasswordCredentialsService.java' that does not convey the meaningful change of adding custom WebApplicationException handling. Consider a more specific title like 'Add custom WebApplicationException handling for ROPC scripts' to clearly indicate the main change.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description mostly follows the template structure with target issue linked (#14148), implementation details provided, and confirmation that no documentation impact exists, though unit/integration tests were not added.
Linked Issues check ✅ Passed The PR implementation aligns with issue #14148 objectives: WebApplicationException from scripts is rethrown unchanged, other exceptions are logged/saved and converted to WebApplicationException with access_denied response containing the required error message about inability to run executeExternalAuthenticate.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the PR objective of enhancing exception handling in ExternalResourceOwnerPasswordCredentialsService.java for ROPC script custom error handling, with no extraneous modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@jans-auth-server/server/src/main/java/io/jans/as/server/service/external/ExternalResourceOwnerPasswordCredentialsService.java`:
- Around line 89-93: The thrown WebApplicationException in
ExternalResourceOwnerPasswordCredentialsService currently builds a Response but
does not attach the original caught exception as the cause; update the throw to
use the WebApplicationException constructor that accepts both a Throwable cause
and the Response (i.e., new WebApplicationException(caughtException, response))
so the original exception (the caught variable in the surrounding catch block,
e.g., "e" or "ex") is preserved in the cause chain while still using
errorResponseFactory to build the Response.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f0262c32-d7e5-490c-a405-07f1f0970f79

📥 Commits

Reviewing files that changed from the base of the PR and between c7638ad and 5e733c1.

📒 Files selected for processing (1)
  • jans-auth-server/server/src/main/java/io/jans/as/server/service/external/ExternalResourceOwnerPasswordCredentialsService.java

Comment on lines +89 to 93
throw new WebApplicationException(errorResponseFactory
.newErrorResponse(Response.Status.INTERNAL_SERVER_ERROR)
.entity(errorResponseFactory.getErrorAsJson(TokenErrorResponseType.ACCESS_DENIED, "", "Unable to run 'executeExternalAuthenticate' method in ROPC script."))
.build());
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Preserve the original exception as the cause.

The new WebApplicationException doesn't include the original exception in its cause chain. While the error is logged at line 87, preserving the cause helps centralized exception handlers or upstream logging capture the full context.

WebApplicationException supports a constructor that accepts both cause and response.

♻️ Proposed fix to preserve stack trace
-            throw new WebApplicationException(errorResponseFactory
+            throw new WebApplicationException(ex, errorResponseFactory
                     .newErrorResponse(Response.Status.INTERNAL_SERVER_ERROR)
                     .entity(errorResponseFactory.getErrorAsJson(TokenErrorResponseType.ACCESS_DENIED, "", "Unable to run 'executeExternalAuthenticate' method in ROPC script."))
                     .build());
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
throw new WebApplicationException(errorResponseFactory
.newErrorResponse(Response.Status.INTERNAL_SERVER_ERROR)
.entity(errorResponseFactory.getErrorAsJson(TokenErrorResponseType.ACCESS_DENIED, "", "Unable to run 'executeExternalAuthenticate' method in ROPC script."))
.build());
}
throw new WebApplicationException(ex, errorResponseFactory
.newErrorResponse(Response.Status.INTERNAL_SERVER_ERROR)
.entity(errorResponseFactory.getErrorAsJson(TokenErrorResponseType.ACCESS_DENIED, "", "Unable to run 'executeExternalAuthenticate' method in ROPC script."))
.build());
🧰 Tools
🪛 PMD (7.24.0)

[Medium] 89-92: PreserveStackTrace (Best Practices): Thrown exception does not preserve the stack trace of exception 'ex' on all code paths

(PreserveStackTrace (Best Practices))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@jans-auth-server/server/src/main/java/io/jans/as/server/service/external/ExternalResourceOwnerPasswordCredentialsService.java`
around lines 89 - 93, The thrown WebApplicationException in
ExternalResourceOwnerPasswordCredentialsService currently builds a Response but
does not attach the original caught exception as the cause; update the throw to
use the WebApplicationException constructor that accepts both a Throwable cause
and the Response (i.e., new WebApplicationException(caughtException, response))
so the original exception (the caught variable in the surrounding catch block,
e.g., "e" or "ex") is preserved in the cause chain while still using
errorResponseFactory to build the Response.

saveScriptError(customScriptConfiguration.getCustomScript(), ex);
return false;
saveScriptError(context.getScript().getCustomScript(), ex);
throw new WebApplicationException(errorResponseFactory
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have WebApplicationException re-thrown above. Why do we break normal execution for Exception ? What case are we trying to cover in line 89 ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @yuriyz ,
The first catch is to catch the exception sent by the Custom ROPC script. LIke below in the Jython code:

exception = context.createWebApplicationException(503,'{"error": "access_denied", "error_description": "User is blacklisted"}')
context.setWebApplicationException(exception)

The second one is to create the exception generally, in case the Script throws any other kind of exception. Like NPE, or Http error while trying to connect to some external endpoint etc.

We are trying to make the script similar to ExternalAuthorizationChallengeService.java file. Here, in the code, we are using context.getAuthzRequest() function. But, in case of ROPC, since, there is no Authorization request, we get NPE in that case.

Hope this helps to understand what we are trying to achieve here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ayushjain0702 We can't apply same behavior as in ExternalAuthorizationChallengeService.java because for authorization challenge we have dedicated script for this endpoint only. ROPC script is used by Authorization Endpoint and by Token Endpoint. Throwing exception can lead to unexpected behavior. For example it's perfectly valid to get ROPC fail and let authorization go on and pass execution to lets say PostAuthn or other script.

You can easily cover case which you've described above by wrapping code inside custom script in try/catch block and throw WebApplicationException explicitly. This will work for NPE, http request failure or other error. In this way response will be propagated outside.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @yuriyz ,

We have tried this. The exception thrown by the ROPC custom script is not handled properly. The exception is only saved in the Script configuration. We have tested this multiple times and only after that we created this pull request.

Can you please suggest any other method of doing it then?

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

jans-auth-server: Enhance ROPC script to throw custom error and error_description

4 participants