-
Notifications
You must be signed in to change notification settings - Fork 297
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
Development
: Enable bearer authentication
#9403
base: develop
Are you sure you want to change the base?
Conversation
WalkthroughThe pull request introduces significant changes to the JWT validation process across multiple classes. The Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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.
Actionable comments posted: 6
🧹 Outside diff range comments (3)
src/main/java/de/tum/cit/aet/artemis/core/web/open/PublicUserJwtResource.java (3)
Line range hint
72-89
: LGTM! Consider standardizing error responses.The changes to the
authorize
method align well with the PR objectives. Returning the JWT token in the response body enables clients that can't use cookies to authenticate successfully. This change maintains RESTful principles and doesn't introduce apparent security risks.A minor suggestion for improvement:
Consider standardizing the error response for consistency with the
authorizeSAML2
method. You could include an error message in the response body or a custom header for unauthorized requests:- return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .header("X-artemisApp-error", "Invalid credentials") + .build();This change would provide more informative error responses across different authentication methods.
Line range hint
1-156
: Consider updating documentation and client-side code.The changes to the
authorize
method successfully enable bearer authentication without affecting the overall structure or responsibility of thePublicUserJwtResource
class. This modification aligns well with the PR objectives and maintains backwards compatibility.To ensure a smooth transition and maintain system coherence:
- Update any relevant API documentation to reflect the new response format of the
authorize
endpoint.- Review and update client-side code that interacts with this endpoint to handle the new response format correctly.
- Consider adding a note in the PR description about potential client-side changes required.
These steps will help maintain consistency across the system and prevent potential integration issues.
Line range hint
1-156
: Refactor suggestion: Improve code reuse for error handling.The code generally adheres well to the provided coding guidelines. To further improve code quality and maintainability:
Consider extracting the error handling logic into a separate method to promote code reuse. This change would align with the principles of avoiding duplication and improving maintainability. Here's a suggested refactor:
private ResponseEntity<String> handleAuthenticationError(String errorMessage) { log.warn(errorMessage); return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .header("X-artemisApp-error", errorMessage) .build(); }Then, in the
authorize
method:catch (BadCredentialsException ex) { return handleAuthenticationError("Wrong credentials during login for user " + loginVM.getUsername()); }This refactoring would make it easier to maintain consistent error handling across different authentication methods in the future.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
📒 Files selected for processing (3)
- src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java (2 hunks)
- src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (2 hunks)
- src/main/java/de/tum/cit/aet/artemis/core/web/open/PublicUserJwtResource.java (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java (1)
Pattern
src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_importssrc/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
Pattern
src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_importssrc/main/java/de/tum/cit/aet/artemis/core/web/open/PublicUserJwtResource.java (1)
Pattern
src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
🔇 Additional comments (4)
src/main/java/de/tum/cit/aet/artemis/core/web/open/PublicUserJwtResource.java (1)
Line range hint
1-156
: Overall assessment: Changes are well-implemented and align with project goals.The modifications to the
PublicUserJwtResource
class successfully implement bearer authentication as intended. The changes are focused, maintain backwards compatibility, and adhere to the project's coding guidelines.Key points:
- The
authorize
method now returns the JWT token in the response body, enabling clients that can't use cookies.- The changes don't introduce apparent security vulnerabilities.
- The code maintains good quality and follows most coding guidelines.
Suggestions for improvement:
- Standardize error responses across authentication methods.
- Extract error handling logic to a separate method for better code reuse.
- Update relevant documentation and client-side code to reflect the changes.
These improvements will enhance code maintainability, consistency, and overall system integration. Once these minor adjustments are addressed, the changes appear ready for merging.
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java (2)
22-22
: LGTM: Import changes align with the new JWT extraction method.The removal of the
Cookie
import and addition ofHttpServletRequest
import are consistent with the changes in thebeforeHandshake
method, supporting the new JWT extraction approach.
Line range hint
1-389
: Overall changes enhance WebSocket authentication while maintaining existing functionality.The modifications to this file successfully implement bearer token authentication for WebSocket connections, as outlined in the PR objectives. The changes are minimal and focused, affecting only the necessary parts of the code:
- Updated imports to support the new JWT extraction method.
- Modified the
beforeHandshake
method to useJWTFilter.extractValidJwt
, enabling both cookie-based and bearer token authentication.These changes improve the flexibility of the authentication mechanism, particularly benefiting clients that cannot use cookies, such as the mentioned VSCode Plugin. The implementation adheres to the coding guidelines, especially the "stateless" principle for REST APIs.
The rest of the file remains unchanged, preserving the existing WebSocket configuration and functionality. This targeted approach minimizes the risk of unintended side effects while achieving the desired enhancement.
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
55-65
: Ensure consistent token validation orderCurrently, the method first checks the cookie for a valid JWT and then the
Authorization
header. Ensure that this order aligns with the intended authentication precedence. If theAuthorization
header should take precedence, consider checking it first.To confirm the desired precedence, please verify if clients are expected to prioritize the
Authorization
header over cookies.
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
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.
Nice changes! I really like the way you adapt to existing code and implement such an important feature in such a lightweight way 🔥
I left a couple of aspects, please answer in the thread. You also have some server-tests failing which might need your attention..
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/web/open/PublicUserJwtResource.java
Outdated
Show resolved
Hide resolved
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.
Actionable comments posted: 1
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
📒 Files selected for processing (1)
- src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
Pattern
src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
🔇 Additional comments (5)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (5)
12-12
: Correct Use of@Nullable
AnnotationThe
@Nullable
annotation is now correctly imported fromorg.springframework.lang.Nullable
, enhancing compatibility within the Spring Framework and avoiding potential conflicts withjavax.annotation.Nullable
.
35-43
: Proper Extraction and Authentication of JWT TokensThe
doFilter
method has been appropriately updated to extract the JWT token usingextractValidJwt
. The authentication is effectively set in theSecurityContextHolder
when a valid token is found, ensuring that both cookie-based and header-based tokens are supported.
54-64
: Efficient Consolidation of Token Extraction LogicThe
extractValidJwt
method efficiently consolidates the logic for retrieving a valid JWT token from both the cookie and the Authorization header. This improves code readability and adheres to the DRY (Don't Repeat Yourself) principle.
72-77
: Robust Handling ingetJwtFromCookie
MethodThe
getJwtFromCookie
method correctly checks for a null cookie and returns the JWT value when available. This ensures robustness in scenarios where the cookie might not be present.
85-91
: Accurate Extraction and Trimming ingetJwtFromBearer
MethodThe
getJwtFromBearer
method accurately extracts the JWT token from the Authorization header and trims any leading or trailing whitespace. This prevents token validation issues due to formatting inconsistencies.
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
General
Enable bearer authentication
General
Enable bearer authenticationGeneral
: Enable bearer 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.
Code LGTM
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.
If possible, could you also add a test that checks if it successfully extracts the Bearer token?
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java
Outdated
Show resolved
Hide resolved
b59f8ad
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.
Actionable comments posted: 2
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
📒 Files selected for processing (2)
- src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java (1 hunks)
- src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java (1)
Pattern
src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_importssrc/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
Pattern
src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
…ture/bearer-support
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.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (2)
65-69
: Consider logging authentication method conflictsWhen both authentication methods are present, it would be helpful to log this security-relevant event for monitoring and debugging purposes.
Apply this diff:
if (cookie != null && authHeader != null) { // Single Method Enforcement: Only one method of authentication is allowed + logger.warn("Request contains both JWT cookie and Authorization header - rejecting request"); httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); return null; }
99-105
: Consider additional validation for bearer token formatWhile the current implementation checks for "Bearer " prefix, consider adding length validation to prevent potential security issues with malformed tokens.
Apply this diff:
private static @Nullable String getJwtFromBearer(@Nullable String jwtBearer) { - if (!StringUtils.hasText(jwtBearer) || !jwtBearer.startsWith("Bearer ")) { + if (!StringUtils.hasText(jwtBearer) || !jwtBearer.startsWith("Bearer ") || jwtBearer.length() < 8) { return null; } return jwtBearer.substring(7).trim(); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (2)
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java
(2 hunks)src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
🔇 Additional comments (2)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (2)
35-46
: LGTM! Clean implementation of dual authentication handling
The changes properly integrate both cookie and bearer token authentication while maintaining thread safety with SecurityContextHolder. The early return on bad request status is a good practice for request validation.
57-78
: Verify consistent JWT extraction across the codebase
Let's ensure that JWT extraction is consistently handled across the codebase to prevent security bypasses.
✅ Verification successful
Let me gather more specific information about JWT token handling to ensure there are no inconsistencies.
Based on the comprehensive analysis of the codebase, I can now provide the final response:
JWT extraction implementation is consistent and secure
The JWT extraction logic in JWTFilter
is the primary and consistent implementation across the codebase. The only other JWT-related authentication occurs in PyrisJobService
which uses a different context (internal service communication) and maintains proper token validation.
- The
JWTFilter
properly handles both cookie and header-based tokens with mutual exclusivity - Token validation is consistently performed through
TokenProvider.validateTokenForAuthority()
- No security bypasses or inconsistent JWT extraction implementations were found
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for other JWT extraction implementations that might bypass security checks
# Search for JWT-related token extractions
echo "Searching for JWT token extractions..."
rg -l "getHeader.*Authorization|getCookie.*jwt" --type java
# Search for SecurityContextHolder usage
echo "Searching for SecurityContextHolder usage..."
rg -l "SecurityContextHolder" --type java
# Search for TokenProvider usage
echo "Searching for TokenProvider usage..."
ast-grep --pattern 'class $_ {
$$$
$x: TokenProvider
$$$
}'
Length of output: 3337
Script:
#!/bin/bash
# Check for actual JWT token extraction implementations
echo "Checking JWT extraction implementations..."
rg -A 5 "getHeader\(\"Authorization\"\)|getCookie.*jwt" --type java
# Check for other security filter implementations
echo "Checking security filter implementations..."
rg -l "extends.*Filter|implements.*Filter" --type java
# Check for TokenProvider usage in authentication context
echo "Checking TokenProvider authentication usage..."
rg -B 2 -A 5 "TokenProvider.*authenticate|validateToken" --type java
Length of output: 18577
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
…into feature/bearer-support
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.
Actionable comments posted: 5
🧹 Outside diff range and nitpick comments (1)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
38-44
: Add logging for authentication failuresWhen authentication fails due to multiple authentication methods being used, the error is silently handled. Consider adding logging to track security-related issues.
try { jwtToken = extractValidJwt(httpServletRequest, this.tokenProvider); } catch (IllegalArgumentException e) { + log.warn("Authentication failed: {}", e.getMessage()); httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST); return; }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (3)
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java
(2 hunks)src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
(2 hunks)src/main/java/de/tum/cit/aet/artemis/core/security/jwt/TokenProvider.java
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/TokenProvider.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
🔇 Additional comments (5)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
117-119
: Verify consistent token validation across the codebase
Let's ensure that the token validation logic is consistently applied across all authentication points.
✅ Verification successful
Let me gather more specific information about the token validation implementation to ensure consistency.
Based on the verification results, I can now provide a final response:
Token validation implementation is consistent and well-tested
The token validation is properly implemented through a single, centralized method validateTokenForAuthority
in the TokenProvider class, which is consistently used across the codebase. The implementation:
- Handles all validation cases (malformed, expired, unsupported tokens)
- Is thoroughly tested with comprehensive test coverage
- Includes security metrics for monitoring invalid tokens
- Is properly integrated with both cookie and bearer token authentication in JWTFilter
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistent token validation across the codebase
# Find all files that might handle JWT validation
echo "Searching for JWT validation patterns..."
rg -l "validateToken|getAuthentication|SecurityContextHolder" --type java
# Check for potential JWT handling without proper validation
echo "Checking for potential JWT handling without validation..."
ast-grep --pattern 'getHeader("Authorization")' --lang java
# Look for other JWT cookie handling
echo "Checking for other JWT cookie handling..."
rg -A 3 "getCookie.*jwt" --type java
Length of output: 6961
Script:
#!/bin/bash
# Check token validation implementation details
# Look for validateTokenForAuthority implementation
echo "Checking TokenProvider validation implementation..."
rg -A 10 "validateTokenForAuthority" --type java
# Check for other token validation methods
echo "Checking other validation methods..."
rg -A 5 "validateToken" --type java
# Look for JWT filter usage
echo "Checking JWT filter configuration..."
ast-grep --pattern 'extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>' --lang java
Length of output: 25403
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/TokenProvider.java (2)
173-176
: Security review: Implementation maintains security standards.
The new getClaim
method:
- Correctly reuses the secure
parseClaims
method which validates the token signature - Maintains existing security measures and error tracking
- Doesn't introduce new security vulnerabilities
173-176
: Verify integration with bearer token handling.
Let's verify how this new method integrates with the bearer token authentication flow.
✅ Verification successful
Let me gather more information about the JWT validation flow and the actual usage of the new method.
Let me check one more aspect to understand the JWT authentication flow and the usage of claims.
Based on the gathered information, I can now provide the final response:
The new getClaim
method is properly integrated with the bearer token authentication flow
The implementation is correctly positioned within the JWT authentication flow:
- The
JWTFilter
properly extracts bearer tokens from the Authorization header - Token validation is handled through
validateTokenForAuthority
method - The new
getClaim
method complements the existing claims extraction functionality, whereclaims.get()
is already used for authority claims
The changes align well with the PR's objective to support bearer authentication for the VSCode plugin, as evidenced by:
- Presence of VSCode-related configurations in the codebase
- Proper bearer token extraction in
JWTFilter
- Flexible claim extraction capability through the new method
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check usage of getClaim method in JWT validation flow
# and integration with bearer token handling
# Check for JWT extraction from Authorization header
rg -l "Authorization.*Bearer" src/
# Check for usage of getClaim method
ast-grep --pattern 'getClaim($_, $_, $_)'
# Check for WebSocket security configuration
fd -e java -e kt --full-path "websocket.*config"
Length of output: 989
Script:
#!/bin/bash
# Check JWT filter implementation and token validation
rg -A 5 "class JWTFilter" src/
rg -A 10 "resolveToken" src/
# Check WebSocket security configuration for JWT usage
cat src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketSecurityConfiguration.java
# Look for other potential JWT claim extractions
rg "claims\.get\(" src/
Length of output: 3255
Script:
#!/bin/bash
# Check the TokenProvider implementation for authentication flow
rg -A 10 "validateToken|authenticate" src/main/java/de/tum/cit/aet/artemis/core/security/jwt/
# Look for bearer token extraction
rg -A 5 "Bearer" src/main/java/de/tum/cit/aet/artemis/core/security/jwt/
# Check for any VSCode plugin related configurations or endpoints
fd vscode src/
rg -l "vscode|VSCode" src/
Length of output: 4458
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java (2)
30-30
: LGTM: Import added for HTTP status codes.
The addition of HttpStatusCode
import is appropriate for the new error handling.
205-205
: Verify JWT validation implementation across the codebase.
The JWT validation has been moved to JWTFilter.extractValidJwt
, which is a good centralization of authentication logic. Let's verify the implementation and test coverage.
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/TokenProvider.java
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/core/config/websocket/WebsocketConfiguration.java
Show resolved
Hide resolved
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.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (2)
65-85
: Add security audit loggingFor security-critical operations, it's important to log authentication attempts and failures. This helps with security auditing and troubleshooting.
Apply this diff to add logging:
+import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JWTFilter extends GenericFilterBean { + private static final Logger logger = LoggerFactory.getLogger(JWTFilter.class); public static @Nullable String extractValidJwt(HttpServletRequest httpServletRequest, TokenProvider tokenProvider) { var cookie = WebUtils.getCookie(httpServletRequest, JWT_COOKIE_NAME); var authHeader = httpServletRequest.getHeader(AUTHORIZATION_HEADER); if (cookie == null && authHeader == null) { + logger.debug("No authentication token found in request"); return null; } if (cookie != null && authHeader != null) { + logger.warn("Multiple authentication methods detected in request from IP: {}", httpServletRequest.getRemoteAddr()); throw new IllegalArgumentException("Multiple authentication methods detected: Both JWT cookie and Bearer token are present"); } String jwtToken = cookie != null ? getJwtFromCookie(cookie) : getJwtFromBearer(authHeader); if (!isJwtValid(tokenProvider, jwtToken)) { + logger.warn("Invalid authentication token detected from IP: {}", httpServletRequest.getRemoteAddr()); return null; } + logger.debug("Valid authentication token processed"); return jwtToken; }
Security concern: JWT tokens are being logged
There are two instances where JWT tokens are being logged, which could potentially expose sensitive authentication information:
- In
TokenProvider.java
:log.info("Invalid JWT token: {}", authToken);
- In
PublicLtiResource.java
:log.info("LTI request: JWT token is invalid: {}", token, e);These logging statements should be modified to:
- Remove the actual token value from the log message
- Use appropriate log levels (e.g., debug for invalid tokens)
- Only log non-sensitive metadata if needed for debugging
🔗 Analysis chain
Line range hint
1-124
: Verify token logging practicesLet's ensure that JWT tokens are not being logged anywhere in the codebase to prevent security risks.
Let me analyze the search results carefully. I notice two instances of token logging in the codebase:
- In
TokenProvider.java
:log.info("Invalid JWT token: {}", authToken);
- In
PublicLtiResource.java
:log.info("LTI request: JWT token is invalid: {}", token, e);Let me verify if these are the only instances and check their context.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for potential JWT token logging # Expected results: No instances of logging JWT tokens should be found echo "Checking for potential JWT token logging..." # Search for logging statements that might contain JWT tokens rg -i "log\.(debug|info|warn|error).*jwt.*token|bearer" --type java # Search for debug print statements that might expose tokens rg -i "system\.out\.print.*jwt.*token|bearer" --type java echo "Note: Review any matches carefully to ensure tokens are not being logged"Length of output: 10227
Script:
#!/bin/bash # Get more context around the logging statements echo "Context for TokenProvider.java logging:" rg -B 5 -A 5 'log\.info.*Invalid JWT token' --type java echo -e "\nContext for PublicLtiResource.java logging:" rg -B 5 -A 5 'LTI request: JWT token is invalid' --type javaLength of output: 2808
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (1)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java
(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
🔇 Additional comments (1)
src/main/java/de/tum/cit/aet/artemis/core/security/jwt/JWTFilter.java (1)
50-53
:
Clear SecurityContext when JWT is invalid
When no valid JWT is found, the SecurityContext should be explicitly cleared to prevent any potential security issues from previous authentications.
Apply this diff to improve security:
if (jwtToken != null) {
Authentication authentication = this.tokenProvider.getAuthentication(jwtToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
+} else {
+ SecurityContextHolder.clearContext();
}
Likely invalid or redundant comment.
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.
Tested on TS9 by sending requests using Postman. Token is received correctly, and you can't use token and authentication header together as expected.
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.
Tested with postman on Ts9. Works as described. Code lgtm to me too
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.
Reapprove after merge
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.
Code reapprove
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.
reapprove
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.
Code approve
Checklist
General
Server
Motivation and Context
For some clients it is best practise or they are only able to use authentication with a
Authorization
Header, so called bearer. One client which is not able to use cookies is the VSCode Plugin. Therefore Artemis should be adjusted to use Bearer Tokens as wellDescription
The Authentication now also accepts JWT in the Authentication Header. It checks first for a valid JWT in the cookie and afterwards in the Authentication Header.
The authenticate endpoint is adjusted accordingly to also return the token in the body
Steps for Testing
Postman testing or code review:
Postman Testing:
ArtemisTokens.postman_collection.json
Send a request to POST
{{base_url}}/api/public/authenticate
Verify that you get a token in the body response
Send a request to GET
{{base_url}}/api/courses/for-dashboard
Verify that you get a 200 response
Send a request to GET
{{base_url}}/api/courses/for-dashboard
with the headerAuthorization
:Bearer {{access_token}}
from the body of the authenticate requestverify that you get a 400 because you used both Authorization Header and Cookie
Delete the cookie in Postman
Send a request to GET
{{base_url}}/api/courses/for-dashboard
with the headerAuthorization
:Bearer {{access_token}}
from the body of the authenticate requestverify you now get a 200 because only the Authorization Header is used
Testserver States
Note
These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.
Review Progress
Test Coverage
Screenshots
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Tests
Chores
@coderabbitai pause