[DEV] select Bearer to be more standard

This commit is contained in:
Edouard DUPIN 2024-01-15 23:56:25 +01:00
parent 0574d5da82
commit f394254f38
4 changed files with 41 additions and 44 deletions

View File

@ -22,7 +22,7 @@ public class JacksonCatcher implements ExceptionMapper<JsonProcessingException>
} }
private RestErrorResponse build(final Exception exception) { private RestErrorResponse build(final Exception exception) {
return new RestErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Catch Unknown Exception", exception.getMessage()); return new RestErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Catch JSON Exception", exception.getMessage());
} }
} }

View File

@ -43,8 +43,8 @@ public class AuthenticationFilter implements ContainerRequestFilter {
private ResourceInfo resourceInfo; private ResourceInfo resourceInfo;
protected final String applicationName; protected final String applicationName;
private static final String AUTHENTICATION_SCHEME = "Yota"; private static final String AUTHENTICATION_SCHEME = "Bearer";
private static final String AUTHENTICATION_TOKEN_SCHEME = "Zota"; private static final String APIKEY = "ApiKey";
public AuthenticationFilter(final String applicationName) { public AuthenticationFilter(final String applicationName) {
this.applicationName = applicationName; this.applicationName = applicationName;
@ -58,7 +58,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
// Access denied for all // Access denied for all
if (method.isAnnotationPresent(DenyAll.class)) { if (method.isAnnotationPresent(DenyAll.class)) {
LOGGER.debug(" ==> deny all {}", requestContext.getUriInfo().getPath()); LOGGER.debug(" ==> deny all {}", requestContext.getUriInfo().getPath());
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access blocked !!!").build()); abortWithForbidden(requestContext, "Access blocked !!!");
return; return;
} }
@ -71,28 +71,28 @@ public class AuthenticationFilter implements ContainerRequestFilter {
// this is a security guard, all the API must define their access level: // this is a security guard, all the API must define their access level:
if (!method.isAnnotationPresent(RolesAllowed.class)) { if (!method.isAnnotationPresent(RolesAllowed.class)) {
LOGGER.error(" ==> missing @RolesAllowed {}", requestContext.getUriInfo().getPath()); LOGGER.error(" ==> missing @RolesAllowed {}", requestContext.getUriInfo().getPath());
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access ILLEGAL !!!").build()); abortWithForbidden(requestContext, "Access ILLEGAL !!!");
return; return;
} }
// Get the Authorization header from the request // Get the Authorization header from the request
String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
String apikeyHeader = requestContext.getHeaderString(APIKEY);
// logger.debug("authorizationHeader: {}", authorizationHeader); // logger.debug("authorizationHeader: {}", authorizationHeader);
if (authorizationHeader == null && method.isAnnotationPresent(PermitTokenInURI.class)) { if (authorizationHeader == null && apikeyHeader == null && method.isAnnotationPresent(PermitTokenInURI.class)) {
final MultivaluedMap<String, String> quaryparam = requestContext.getUriInfo().getQueryParameters(); final MultivaluedMap<String, String> quaryparam = requestContext.getUriInfo().getQueryParameters();
for (final Entry<String, List<String>> item : quaryparam.entrySet()) { for (final Entry<String, List<String>> item : quaryparam.entrySet()) {
if (item.getKey().equals(HttpHeaders.AUTHORIZATION)) { if ((authorizationHeader == null && HttpHeaders.AUTHORIZATION.equals(item.getKey())) && !item.getValue().isEmpty()) {
if (!item.getValue().isEmpty()) {
authorizationHeader = item.getValue().get(0); authorizationHeader = item.getValue().get(0);
} }
break; if ((apikeyHeader == null && APIKEY.equals(item.getKey())) && !item.getValue().isEmpty()) {
apikeyHeader = item.getValue().get(0);
} }
} }
} }
// logger.debug("authorizationHeader: {}", authorizationHeader); // logger.debug("authorizationHeader: {}", authorizationHeader);
final boolean isApplicationToken = isApplicationTokenBasedAuthentication(authorizationHeader); final boolean isApplicationToken = apikeyHeader != null;
final boolean isJwtToken = isTokenBasedAuthentication(authorizationHeader); final boolean isJwtToken = isTokenBasedAuthentication(authorizationHeader);
// Validate the Authorization header data Model "Yota jwt.to.ken" "Zota tokenId:hash(token)"
if (!isApplicationToken && !isJwtToken) { if (!isApplicationToken && !isJwtToken) {
LOGGER.warn("REJECTED unauthorized: {}", requestContext.getUriInfo().getPath()); LOGGER.warn("REJECTED unauthorized: {}", requestContext.getUriInfo().getPath());
abortWithUnauthorized(requestContext, "REJECTED unauthorized: " + requestContext.getUriInfo().getPath()); abortWithUnauthorized(requestContext, "REJECTED unauthorized: " + requestContext.getUriInfo().getPath());
@ -100,7 +100,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
} }
UserByToken userByToken = null; UserByToken userByToken = null;
if (isJwtToken) { if (isJwtToken) {
// Extract the token from the Authorization header (Remove "Yota ") // Extract the token from the Authorization header (Remove "Bearer ")
final String token = authorizationHeader.substring(AUTHENTICATION_SCHEME.length()).trim(); final String token = authorizationHeader.substring(AUTHENTICATION_SCHEME.length()).trim();
// logger.debug("token: {}", token); // logger.debug("token: {}", token);
try { try {
@ -116,9 +116,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
return; return;
} }
} else { } else {
// Extract the token from the Authorization header (Remove "Zota ") final String token = apikeyHeader.trim();
final String token = authorizationHeader.substring(AUTHENTICATION_TOKEN_SCHEME.length()).trim();
// logger.debug("token: {}", token);
try { try {
userByToken = validateToken(token); userByToken = validateToken(token);
} catch (final Exception e) { } catch (final Exception e) {
@ -164,13 +162,6 @@ public class AuthenticationFilter implements ContainerRequestFilter {
return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " "); return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");
} }
private boolean isApplicationTokenBasedAuthentication(final String authorizationHeader) {
// Check if the Authorization header is valid
// It must not be null and must be prefixed with "Bearer" plus a whitespace
// The authentication scheme comparison must be case-insensitive
return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_TOKEN_SCHEME.toLowerCase() + " ");
}
private void abortWithUnauthorized(final ContainerRequestContext requestContext, final String message) { private void abortWithUnauthorized(final ContainerRequestContext requestContext, final String message) {
// Abort the filter chain with a 401 status code response // Abort the filter chain with a 401 status code response
@ -182,6 +173,12 @@ public class AuthenticationFilter implements ContainerRequestFilter {
.type(MediaType.APPLICATION_JSON).build()); .type(MediaType.APPLICATION_JSON).build());
} }
private void abortWithForbidden(final ContainerRequestContext requestContext, final String message) {
final RestErrorResponse ret = new RestErrorResponse(Response.Status.FORBIDDEN, "FORBIDDEN", message);
LOGGER.error("Error UUID={}", ret.uuid);
requestContext.abortWith(Response.status(ret.status).header(HttpHeaders.WWW_AUTHENTICATE, message).entity(ret).type(MediaType.APPLICATION_JSON).build());
}
protected UserByToken validateToken(final String authorization) throws Exception { protected UserByToken validateToken(final String authorization) throws Exception {
LOGGER.info("Must be Override by the application implmentation, otherwise it dose not work"); LOGGER.info("Must be Override by the application implmentation, otherwise it dose not work");
return null; return null;

View File

@ -35,13 +35,13 @@ class MySecurityContext implements SecurityContext {
@Override @Override
public boolean isSecure() { public boolean isSecure() {
return this.sheme.equalsIgnoreCase("https"); return "https".equalsIgnoreCase(this.sheme);
} }
@Override @Override
public String getAuthenticationScheme() { public String getAuthenticationScheme() {
if (this.contextPrincipale.userByToken != null) { if (this.contextPrincipale.userByToken != null) {
return "Zota"; return "Bearer";
} }
return null; return null;
} }

View File

@ -40,7 +40,7 @@ public class RESTApi {
final HttpClient client = HttpClient.newHttpClient(); final HttpClient client = HttpClient.newHttpClient();
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1).uri(URI.create(this.baseUrl + urlOffset)); Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1).uri(URI.create(this.baseUrl + urlOffset));
if (this.token != null) { if (this.token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + this.token); requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Bearer " + this.token);
} }
final HttpRequest request = requestBuilding.GET().build(); final HttpRequest request = requestBuilding.GET().build();
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString()); final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
@ -111,7 +111,7 @@ public class RESTApi {
LOGGER.trace("call {}: {}", model, URI.create(this.baseUrl + urlOffset)); LOGGER.trace("call {}: {}", model, URI.create(this.baseUrl + urlOffset));
LOGGER.trace("DATA: {}", body); LOGGER.trace("DATA: {}", body);
if (this.token != null) { if (this.token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + this.token); requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Bearer " + this.token);
} }
if (body == null) { if (body == null) {
body = ""; body = "";
@ -143,7 +143,7 @@ public class RESTApi {
String body = null; String body = null;
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1).uri(URI.create(this.baseUrl + urlOffset)); Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1).uri(URI.create(this.baseUrl + urlOffset));
if (this.token != null) { if (this.token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + this.token); requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Bearer " + this.token);
} }
if (data == null) { if (data == null) {
body = ""; body = "";
@ -171,7 +171,7 @@ public class RESTApi {
final HttpClient client = HttpClient.newHttpClient(); final HttpClient client = HttpClient.newHttpClient();
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1).uri(URI.create(this.baseUrl + urlOffset)); Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1).uri(URI.create(this.baseUrl + urlOffset));
if (this.token != null) { if (this.token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + this.token); requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Bearer " + this.token);
} }
final HttpRequest request = requestBuilding.DELETE().build(); final HttpRequest request = requestBuilding.DELETE().build();
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString()); final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());