Skip to content
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

Fix for gh-226 #227

Merged
merged 2 commits into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix gh-226. Also updated some @param javadocs that had gotten out of …
…sync with the actual method signatures and a few typos. Added Angular build output cache folders to gitignore.
  • Loading branch information
Ebbe Brandstrup committed Aug 30, 2024
commit e9527f0195ffa407f8316b4e66fe07c28face154
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ target/
/dist
/tmp
/out-tsc
**/.angular/cache

# dependencies
**/node_modules/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public void handle(ServerWebExchange exchange, Mono<CsrfToken> csrfToken) {
@Override
public Mono<String> resolveCsrfTokenValue(ServerWebExchange exchange, CsrfToken csrfToken) {
/*
* If the request contains a X-XSRF-TOKEN header, use use it. This applies when a single-page application includes the header value automatically,
* If the request contains a X-XSRF-TOKEN header, use it. This applies when a single-page application includes the header value automatically,
* which was obtained via a cookie containing the raw CsrfToken. In all other cases (e.g. if the request contains a request parameter), use
* XorCsrfTokenRequestAttributeHandler to resolve the CsrfToken. This applies when a server-side rendered form includes the _csrf request parameter
* as a hidden input.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.c4_soft.springaddons.security.oidc.starter.reactive.resourceserver;

import java.nio.charset.Charset;
import java.sql.Date;
Copy link
Owner

Choose a reason for hiding this comment

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

I think we want java.util.Date here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Gotcha - good catch. IntelliJ auto import and I should have caught that while committing.

import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -228,8 +229,8 @@ SpringAddonsReactiveJwtDecoderFactory springAddonsJwtDecoderFactory() {
/**
* Provides with multi-tenancy: builds a ReactiveAuthenticationManagerResolver per provided OIDC issuer URI
*
* @param auth2ResourceServerProperties "spring.security.oauth2.resourceserver" configuration properties
* @param addonsProperties "com.c4-soft.springaddons.oidc" configuration properties
* @param opPropertiesResolver "com.c4-soft.springaddons.oidc" configuration properties
* @param jwtDecoderFactory something to build a JWT decoder from OpenID Provider configuration properties
* @param jwtAuthenticationConverter converts from a {@link Jwt} to an {@link Authentication} implementation
* @return Multi-tenant {@link ReactiveAuthenticationManagerResolver} (one for each configured issuer)
*/
Expand Down Expand Up @@ -277,7 +278,7 @@ WebFilter csrfCookieWebFilter() {
* Converter bean from {@link Jwt} to {@link AbstractAuthenticationToken}
*
* @param authoritiesConverter converts access-token claims into Spring authorities
* @param authenticationFactory builds an {@link Authentication} instance from access-token string and claims
* @param opPropertiesResolver "com.c4-soft.springaddons.oidc" configuration properties
* @return a converter from {@link Jwt} to {@link AbstractAuthenticationToken}
*/
@Conditional(DefaultJwtAbstractAuthenticationTokenConverterCondition.class)
Expand All @@ -302,7 +303,8 @@ ReactiveJwtAbstractAuthenticationTokenConverter jwtAuthenticationConverter(
* Converter bean from successful introspection result to {@link Authentication} instance
*
* @param authoritiesConverter converts access-token claims into Spring authorities
* @param authenticationFactory builds an {@link Authentication} instance from access-token string and claims
* @param addonsProperties "com.c4-soft.springaddons.oidc" configuration properties
* @param resourceServerProperties Spring Boot standard resource server configuration properties
* @return a converter from successful introspection result to {@link Authentication} instance
*/
@Conditional(DefaultOpaqueTokenAuthenticationConverterCondition.class)
Expand Down Expand Up @@ -330,8 +332,8 @@ ReactiveOpaqueTokenAuthenticationConverter introspectionAuthenticationConverter(
new OAuth2AccessToken(
OAuth2AccessToken.TokenType.BEARER,
introspectedToken,
Instant.ofEpochSecond(((Integer) authenticatedPrincipal.getAttribute(OAuth2TokenIntrospectionClaimNames.IAT)).longValue()),
Instant.ofEpochSecond(((Integer) authenticatedPrincipal.getAttribute(OAuth2TokenIntrospectionClaimNames.EXP)).longValue())),
toInstant(authenticatedPrincipal.getAttribute(OAuth2TokenIntrospectionClaimNames.IAT)),
toInstant(authenticatedPrincipal.getAttribute(OAuth2TokenIntrospectionClaimNames.EXP))),
authoritiesConverter.convert(authenticatedPrincipal.getAttributes())));
}

Expand All @@ -347,4 +349,24 @@ CorsWebFilter corsFilter(SpringAddonsOidcProperties addonsProperties) {

return ReactiveConfigurationSupport.getCorsFilterBean(corsProps);
}

private static final Instant toInstant(Object claim) {
if (claim == null) {
return null;
}
if (claim instanceof Instant i) {
return i;
}
if (claim instanceof Date d) {
return d.toInstant();
}
if (claim instanceof Integer i) {
return Instant.ofEpochSecond((i).longValue());
} else if (claim instanceof Long l) {
return Instant.ofEpochSecond(l);
} else {
return null;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ AuthenticationEntryPoint authenticationEntryPoint() {
* Converter bean from {@link Jwt} to {@link AbstractAuthenticationToken}
*
* @param authoritiesConverter converts access-token claims into Spring authorities
* @param addonsProperties spring-addons configuration properties
* @param opPropertiesResolver spring-addons configuration properties
* @return a converter from {@link Jwt} to {@link AbstractAuthenticationToken}
*/
@Conditional(DefaultJwtAbstractAuthenticationTokenConverterCondition.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void whenRequestPathMatchesAuthorizationCodePattern_thenClientRegistrationIdIsRe
}

@Test
void whenRequestPatDoesNothMatcheAuthorizationCodePattern_thenClientRegistrationIdIsReturned() {
void whenRequestPathDoesNotMatchAuthorizationCodePattern_thenClientRegistrationIdIsReturned() {
final var actual = SpringAddonsServerOAuth2AuthorizationRequestResolver.resolveRegistrationId("/login/authorization/authorization-code");
assertNull(actual);
}
Expand Down