Skip to content

Commit

Permalink
Feature/oauth logging docu (#58)
Browse files Browse the repository at this point in the history
* Add oauth logging and docu.

---------

Co-authored-by: Sven Haag <[email protected]>
  • Loading branch information
cuioss and Sven Haag committed Aug 29, 2024
1 parent 1123960 commit f47fa07
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -463,6 +473,7 @@ private Optional<String> 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)) {
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<String, Object> userInfo = client.getUserInfo();
log.debug("successfully retrieved userinfo");
log.trace("userinfo: {}", userInfo);

var baseAuthenticatedUserInfoBuilder = BaseAuthenticatedUserInfo.builder().authenticated(true)
.contextMapElement(OauthAuthenticatedUserInfo.TOKEN_SCOPES_KEY, scopes)
Expand Down Expand Up @@ -229,7 +254,6 @@ public String retrieveClientToken(String scopes) {
log.warn(e, RETRIEVE_CLIENT_TOKEN_FAILED_MSG);
return null;
}

}

@Override
Expand All @@ -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);
Expand All @@ -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);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,31 @@
*/
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.
*/
@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);
}
}
}

0 comments on commit f47fa07

Please sign in to comment.