diff --git a/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/Oauth2Service.java b/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/Oauth2Service.java index 7a9004b9..2a49ce7e 100644 --- a/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/Oauth2Service.java +++ b/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/Oauth2Service.java @@ -76,10 +76,10 @@ AuthenticatedUserInfo createAuthenticatedUserInfo(HttpServletRequest servletRequ String retrieveClientToken(String scopes); /** - * refresh the current access token + * Refresh the {@link Token} in the current users context map. * - * @param currentUser - * @return + * @param currentUser current oauth user + * @return access token */ String refreshToken(OauthAuthenticatedUserInfo currentUser); } diff --git a/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/impl/Oauth2AuthenticationFacadeImpl.java b/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/impl/Oauth2AuthenticationFacadeImpl.java index fc8ba59a..20876f70 100644 --- a/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/impl/Oauth2AuthenticationFacadeImpl.java +++ b/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/impl/Oauth2AuthenticationFacadeImpl.java @@ -324,17 +324,27 @@ public String retrieveToken(final String scopes) { LOGGER.trace("retrieveToken for scopes: {}", scopes); final var currentUser = retrieveCurrentUserIfPresent(servletRequestProvider.get()); String idToken = null; + if (currentUser.isPresent()) { - final var token = currentUser.get().getToken(); + LOGGER.debug("we have a user"); + final var accessToken = checkAndRetrieveToken(currentUser.get(), scopes); if (null != accessToken) { + LOGGER.debug("accessToken present. returning accessToken."); return accessToken; } + + final var token = currentUser.get().getToken(); if (token != null) { + LOGGER.debug("CUI Token present. extracting idToken."); idToken = token.getId_token(); + } else { + LOGGER.debug("No CUI Token available. Cannot set idToken."); } } - LOGGER.debug("token not present, redirecting to oauth server"); + + LOGGER.debug("accessToken not present, redirecting to oauth server using idToken={}.", null != idToken); + LOGGER.trace("using idToken: {}", idToken); sendRedirect(scopes, idToken); return null; } @@ -463,6 +473,7 @@ private Optional getIdTokenFromCurrentUser() { private String checkAndRetrieveToken(final OauthAuthenticatedUserInfo currentUser, final String scopes) { final var token = currentUser.getToken(); if (checkToken(token, currentUser.getTokenTimestamp())) { + LOGGER.debug("token is valid."); var allFound = true; final var existing = Splitter.on(' ').omitEmptyStrings().splitToList(currentUser.getScopes()); for (final String requested : Splitter.on(' ').omitEmptyStrings().splitToList(scopes)) { @@ -487,11 +498,14 @@ private static boolean checkToken(final Token token, final Integer timestamp) { return false; } if (MoreStrings.isEmpty(token.getExpires_in())) { + LOGGER.trace("token has no expiration. token is valid!"); return true; } try { final var expires = timestamp + Integer.parseInt(token.getExpires_in()) - 10; - return expires > (int) (System.currentTimeMillis() / 1000L); + final boolean valid = expires > (int) (System.currentTimeMillis() / 1000L); + LOGGER.trace("checked expire time. token valid?: {}", valid); + return valid; } catch (final NumberFormatException e) { LOGGER.warn("Portal-149: Oauth2 token.expires_in not a valid number", e); return false; diff --git a/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/impl/Oauth2ServiceImpl.java b/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/impl/Oauth2ServiceImpl.java index 918d16d8..9dda067a 100644 --- a/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/impl/Oauth2ServiceImpl.java +++ b/modules/authentication/portal-authentication-oauth/src/main/java/de/cuioss/portal/authentication/oauth/impl/Oauth2ServiceImpl.java @@ -119,19 +119,35 @@ public void filter(ClientRequestContext requestContext) { @Override public AuthenticatedUserInfo createAuthenticatedUserInfo(final HttpServletRequest servletRequest, - final UrlParameter code, final UrlParameter state, final String scopes, final String codeVerifier) { + final UrlParameter code, final UrlParameter state, final String scopes, final String codeVerifier) { + requireNonNull(servletRequest); requireNonNull(code); requireNonNull(state); requireNonNull(emptyToNull(scopes)); + var configuration = configurationProvider.get(); Token token; + final var builder = new CuiRestClientBuilder(log) .basicAuth(configuration.getClientId(), configuration.getClientSecret()) .register(new AcceptJsonHeaderFilter()); - try (final var requestToken = builder.url(configuration.getTokenUri().trim()).build(RequestToken.class)) { - token = requestToken.requestToken("authorization_code", code.getValue(), state.getValue(), codeVerifier, - configuration.getExternalContextPath().trim() + servletRequest.getRequestURI()); + + final String tokenUri = configuration.getTokenUri().trim(); + final String redirectUri = configuration.getExternalContextPath().trim() + servletRequest.getRequestURI(); + log.debug("creating auth user info with scopes='{}', tokenUri='{}', redirectUri='{}'", + scopes, tokenUri, redirectUri); + + try (final RequestToken requestToken = builder.url(tokenUri).build(RequestToken.class)) { + token = requestToken.requestToken( + "authorization_code", + code.getValue(), + state.getValue(), + codeVerifier, + redirectUri + ); + log.trace("received token='{}' for scopes='{}', requestUri={}", + token, scopes, servletRequest.getRequestURI()); } catch (IllegalArgumentException e) { log.warn("Portal-106: Retrieving request token failed", e); return null; @@ -154,11 +170,20 @@ public AuthenticatedUserInfo retrieveAuthenticatedUser(String scopes, Token toke private AuthenticatedUserInfo retrieveAuthenticatedUser(String scopes, Oauth2Configuration configuration, Token token, int tokenTimestamp) { - final var builder = new CuiRestClientBuilder(log).register(new AcceptJsonHeaderFilter()); - try (var client = builder.url(configuration.getUserInfoUri().trim()).bearerAuthToken(token.getAccess_token()) - .build(RequestUserInfo.class)) { - var userInfo = client.getUserInfo(); + final String userInfoUri = configuration.getUserInfoUri().trim(); + final CuiRestClientBuilder builder = new CuiRestClientBuilder(log) + .register(new AcceptJsonHeaderFilter()) + .bearerAuthToken(token.getAccess_token()); + + log.trace("retrieving userinfo for authenticated user. userInfoUri={}, access_token={}", + userInfoUri, token.getAccess_token()); + + try (RequestUserInfo client = builder.url(userInfoUri).build(RequestUserInfo.class)) { + + Map userInfo = client.getUserInfo(); + log.debug("successfully retrieved userinfo"); + log.trace("userinfo: {}", userInfo); var baseAuthenticatedUserInfoBuilder = BaseAuthenticatedUserInfo.builder().authenticated(true) .contextMapElement(OauthAuthenticatedUserInfo.TOKEN_SCOPES_KEY, scopes) @@ -229,7 +254,6 @@ public String retrieveClientToken(String scopes) { log.warn(e, RETRIEVE_CLIENT_TOKEN_FAILED_MSG); return null; } - } @Override @@ -243,11 +267,14 @@ public String refreshToken(OauthAuthenticatedUserInfo currentUser) { var token = requestToken.requestToken("refresh_token", currentUser.getToken().getRefresh_token()); if (null != token) { + log.debug("successfully retrieved new token"); + log.trace("new token: {}", token); currentUser.getContextMap().put(OauthAuthenticatedUserInfo.TOKEN_KEY, token); currentUser.getContextMap().put(OauthAuthenticatedUserInfo.TOKEN_TIMESTAMP_KEY, (int) (System.currentTimeMillis() / 1000L)); return token.getAccess_token(); } + log.debug("no token received"); return null; } catch (WebApplicationException e) { log.warn(e, RETRIEVE_CLIENT_TOKEN_FAILED_MSG); @@ -263,6 +290,5 @@ public String refreshToken(OauthAuthenticatedUserInfo currentUser) { public String calcEncodedRedirectUrl(final String url) { requireNonNull(url); return encode(configurationProvider.get().getExternalContextPath().trim() + url, StandardCharsets.UTF_8); - } } diff --git a/modules/micro-profile/portal-mp-rest-client/src/main/java/de/cuioss/portal/restclient/BearerTokenAuthFilter.java b/modules/micro-profile/portal-mp-rest-client/src/main/java/de/cuioss/portal/restclient/BearerTokenAuthFilter.java index 1cf96a3f..56284585 100644 --- a/modules/micro-profile/portal-mp-rest-client/src/main/java/de/cuioss/portal/restclient/BearerTokenAuthFilter.java +++ b/modules/micro-profile/portal-mp-rest-client/src/main/java/de/cuioss/portal/restclient/BearerTokenAuthFilter.java @@ -15,13 +15,14 @@ */ package de.cuioss.portal.restclient; +import de.cuioss.tools.logging.CuiLogger; import jakarta.ws.rs.client.ClientRequestContext; import jakarta.ws.rs.client.ClientRequestFilter; import jakarta.ws.rs.core.HttpHeaders; - -import de.cuioss.tools.string.MoreStrings; import lombok.RequiredArgsConstructor; +import static de.cuioss.tools.string.MoreStrings.isEmpty; + /** * Client filter that will do token authentication. You must allocate it and * then register it with the Client or WebTarget. @@ -29,12 +30,16 @@ @RequiredArgsConstructor public class BearerTokenAuthFilter implements ClientRequestFilter { + private static final CuiLogger LOGGER = new CuiLogger(BearerTokenAuthFilter.class); + private static final String AUTH_HEADER_PREFIX = "Bearer "; + private final String token; @Override public void filter(ClientRequestContext requestContext) { - if (!MoreStrings.isEmpty(token)) { - requestContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, "Bearer " + token); + LOGGER.trace("token: {}", token); + if (!isEmpty(token)) { + requestContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, AUTH_HEADER_PREFIX + token); } } }