diff --git a/.classpath b/.classpath index 1f5e859..5b0c41a 100644 --- a/.classpath +++ b/.classpath @@ -25,7 +25,7 @@ - + diff --git a/README.md b/README.md index 3f250f6..216d737 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,6 @@ Reformat XML file like the pom.xml XMLLINT_INDENT=" " xmllint --format "back/pom.xml" -o "back/pom.xml" ``` - Enable the pre-commit checker ----------------------------- @@ -94,6 +93,8 @@ Enable the pre-commit checker > **_Note_**: You can change the code in `.git/hooks/pre-commit` by replacing `formatter:verify` with `formatter:format` to auto format the code @ every commit + + Add Gitea in the dependency for the registry: ============================================= diff --git a/src/org/kar/archidata/filter/AuthenticationFilter.java b/src/org/kar/archidata/filter/AuthenticationFilter.java index f0aee38..a888698 100644 --- a/src/org/kar/archidata/filter/AuthenticationFilter.java +++ b/src/org/kar/archidata/filter/AuthenticationFilter.java @@ -42,14 +42,14 @@ public class AuthenticationFilter implements ContainerRequestFilter { @Context private ResourceInfo resourceInfo; protected final String applicationName; - - private static final String AUTHENTICATION_SCHEME = "Bearer"; - private static final String APIKEY = "ApiKey"; - + + public static final String AUTHENTICATION_SCHEME = "Bearer"; + public static final String APIKEY = "ApiKey"; + public AuthenticationFilter(final String applicationName) { this.applicationName = applicationName; } - + @Override public void filter(final ContainerRequestContext requestContext) throws IOException { /* logger.debug("-----------------------------------------------------"); logger.debug("---- Check if have authorization ----"); @@ -61,7 +61,7 @@ public class AuthenticationFilter implements ContainerRequestFilter { abortWithForbidden(requestContext, "Access blocked !!!"); return; } - + // Access allowed for all if (method.isAnnotationPresent(PermitAll.class)) { // logger.debug(" ==> permit all " + requestContext.getUriInfo().getPath()); @@ -74,7 +74,7 @@ public class AuthenticationFilter implements ContainerRequestFilter { abortWithForbidden(requestContext, "Access ILLEGAL !!!"); return; } - + // Get the Authorization header from the request String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); String apikeyHeader = requestContext.getHeaderString(APIKEY); @@ -129,7 +129,7 @@ public class AuthenticationFilter implements ContainerRequestFilter { abortWithUnauthorized(requestContext, "get a NULL application ..."); return; } - + } // create the security context model: final String scheme = requestContext.getUriInfo().getRequestUri().getScheme(); @@ -154,16 +154,16 @@ public class AuthenticationFilter implements ContainerRequestFilter { requestContext.setSecurityContext(userContext); // logger.debug("Get local user : {} / {}", user, userByToken); } - + private boolean isTokenBasedAuthentication(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_SCHEME.toLowerCase() + " "); } - + private void abortWithUnauthorized(final ContainerRequestContext requestContext, final String message) { - + // Abort the filter chain with a 401 status code response // The WWW-Authenticate header is sent along with the response LOGGER.warn("abortWithUnauthorized:"); @@ -172,18 +172,18 @@ public class AuthenticationFilter implements ContainerRequestFilter { requestContext.abortWith(Response.status(ret.status).header(HttpHeaders.WWW_AUTHENTICATE, AUTHENTICATION_SCHEME + " base64(HEADER).base64(CONTENT).base64(KEY)").entity(ret) .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 { LOGGER.info("Must be Override by the application implmentation, otherwise it dose not work"); return null; } - + // must be override to be good implementation protected UserByToken validateJwtToken(final String authorization) throws Exception { // logger.debug(" validate token : " + authorization); diff --git a/src/org/kar/archidata/tools/JWTWrapper.java b/src/org/kar/archidata/tools/JWTWrapper.java index 6ea6646..a209c1d 100644 --- a/src/org/kar/archidata/tools/JWTWrapper.java +++ b/src/org/kar/archidata/tools/JWTWrapper.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import org.kar.archidata.filter.AuthenticationFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +34,7 @@ import com.nimbusds.jwt.SignedJWT; class TestSigner implements JWSSigner { public static String test_signature = "TEST_SIGNATURE_FOR_LOCAL_TEST_AND_TEST_E2E"; - + /** Signs the specified {@link JWSObject#getSigningInput input} of a {@link JWSObject JWS object}. * * @param header The JSON Web Signature (JWS) header. Must specify a supported JWS algorithm and must not be {@code null}. @@ -47,13 +48,13 @@ class TestSigner implements JWSSigner { public Base64URL sign(final JWSHeader header, final byte[] signingInput) throws JOSEException { return new Base64URL(test_signature); } - + @Override public Set supportedJWSAlgorithms() { // TODO Auto-generated method stub return Set.of(JWSAlgorithm.RS256); } - + @Override public JCAContext getJCAContext() { // TODO Auto-generated method stub @@ -63,20 +64,20 @@ class TestSigner implements JWSSigner { public class JWTWrapper { static final Logger LOGGER = LoggerFactory.getLogger(JWTWrapper.class); - - private static RSAKey rsaJWK = null;; + + private static RSAKey rsaJWK = null; private static RSAKey rsaPublicJWK = null; - + public static class PublicKey { public String key; - + public PublicKey(final String key) { this.key = key; } - + public PublicKey() {} } - + public static void initLocalTokenRemote(final String ssoUri, final String application) throws IOException, ParseException { // check Token: final URL obj = new URL(ssoUri + "public_key"); @@ -89,14 +90,14 @@ public class JWTWrapper { con.setRequestProperty("Accept", "application/json"); final String ssoToken = ConfigBaseVariable.ssoToken(); if (ssoToken != null) { - con.setRequestProperty("Authorization", "Zota " + ssoToken); + con.setRequestProperty(AuthenticationFilter.APIKEY, ssoToken); } final int responseCode = con.getResponseCode(); - + // LOGGER.debug("GET Response Code :: {}", responseCode); if (responseCode == HttpURLConnection.HTTP_OK) { // success final BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); - + String inputLine; final StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { @@ -112,7 +113,7 @@ public class JWTWrapper { } LOGGER.debug("GET JWT validator token not worked response code {} from {} ", responseCode, obj); } - + public static void initLocalToken(final String baseUUID) throws Exception { // RSA signatures require a public and private RSA key pair, the public key // must be made known to the JWS recipient in order to verify the signatures @@ -136,7 +137,7 @@ public class JWTWrapper { rsaPublicJWK = null; } } - + public static void initValidateToken(final String publicKey) { try { rsaPublicJWK = RSAKey.parse(publicKey); @@ -144,16 +145,16 @@ public class JWTWrapper { e.printStackTrace(); LOGGER.debug("Can not retrieve public Key !!!!!!!! RSAKey='{}'", publicKey); } - + } - + public static String getPublicKeyJson() { if (rsaPublicJWK == null) { return null; } return rsaPublicJWK.toJSONString(); } - + public static java.security.interfaces.RSAPublicKey getPublicKeyJava() throws JOSEException { if (rsaPublicJWK == null) { return null; @@ -161,7 +162,7 @@ public class JWTWrapper { // Convert back to std Java interface return rsaPublicJWK.toRSAPublicKey(); } - + /** Create a token with the provided elements * @param userID UniqueId of the USER (global unique ID) * @param userLogin Login of the user (never change) @@ -178,12 +179,12 @@ public class JWTWrapper { try { // Create RSA-signer with the private key final JWSSigner signer = new RSASSASigner(rsaJWK); - + LOGGER.warn("timeOutInMunites= {}", timeOutInMunites); final Date now = new Date(); LOGGER.warn("now = {}", now); final Date expiration = new Date(new Date().getTime() - 60 * timeOutInMunites * 1000 /* millisecond */); - + LOGGER.warn("expiration= {}", expiration); final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID)).claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now) .expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning @@ -194,7 +195,7 @@ public class JWTWrapper { // Prepare JWT with claims set final JWTClaimsSet claimsSet = builder.build(); final SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT)/* .keyID(rsaJWK.getKeyID()) */.build(), claimsSet); - + // Compute the RSA signature signedJWT.sign(signer); // serialize the output... @@ -204,7 +205,7 @@ public class JWTWrapper { } return null; } - + public static JWTClaimsSet validateToken(final String signedToken, final String isuer, final String application) { try { // On the consumer side, parse the JWS and verify its RSA signature @@ -244,14 +245,12 @@ public class JWTWrapper { // LOGGER.debug("JWT token is verified 'alice' =?= '" + signedJWT.getJWTClaimsSet().getSubject() + "'"); // LOGGER.debug("JWT token isuer 'https://c2id.com' =?= '" + signedJWT.getJWTClaimsSet().getIssuer() + "'"); return signedJWT.getJWTClaimsSet(); - } catch (final JOSEException ex) { - ex.printStackTrace(); - } catch (final ParseException e) { + } catch (final JOSEException | ParseException e) { e.printStackTrace(); } return null; } - + public static String createJwtTestToken(final long userID, final String userLogin, final String isuer, final String application, final Map> rights) { if (!ConfigBaseVariable.getTestMode()) { LOGGER.error("Test mode disable !!!!!"); @@ -259,10 +258,10 @@ public class JWTWrapper { } try { final int timeOutInMunites = 3600; - + final Date now = new Date(); final Date expiration = new Date(new Date().getTime() + timeOutInMunites * 1000 /* ms */); - + final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID)).claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now) .expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning // add right if needed: @@ -272,10 +271,10 @@ public class JWTWrapper { // Prepare JWT with claims set final JWTClaimsSet claimsSet = builder.build(); final SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT)/* .keyID(rsaJWK.getKeyID()) */.build(), claimsSet); - + // Compute the RSA signature signedJWT.sign(new TestSigner()); - + // serialize the output... return signedJWT.serialize(); } catch (final Exception ex) {