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

Feature/oauth logging docu #58

Merged
merged 3 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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='{}'",
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe this should be TRACE due to sensible data in the tokenuri like the nonce?!

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);
}
}
}
Loading