From 4b251da1275fbf027204236de97c8c628028dc2b Mon Sep 17 00:00:00 2001 From: Thorsten Hell Date: Tue, 2 Feb 2021 15:27:32 +0100 Subject: [PATCH] working on #233: initial work towards JWT Auth --- .classpath | 55 +++++++ .factorypath | 79 ++++++++++ .project | 23 +++ .settings/org.eclipse.core.resources.prefs | 6 + .settings/org.eclipse.jdt.apt.core.prefs | 4 + .settings/org.eclipse.jdt.core.prefs | 9 ++ .settings/org.eclipse.m2e.core.prefs | 4 + .vscode/launch.json | 146 ++++++++++++++++++ pom.xml | 38 ++++- .../server/localserver/_class/ClassCache.java | 1 + .../impls/proxy/UserServiceImpl.java | 120 +++++++++++--- src/main/java/Sirius/server/newuser/User.java | 20 +++ 12 files changed, 479 insertions(+), 26 deletions(-) create mode 100644 .classpath create mode 100644 .factorypath create mode 100644 .project create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.apt.core.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 .vscode/launch.json diff --git a/.classpath b/.classpath new file mode 100644 index 00000000..50244fea --- /dev/null +++ b/.classpath @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.factorypath b/.factorypath new file mode 100644 index 00000000..a86185fc --- /dev/null +++ b/.factorypath @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 00000000..e3d7a31f --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + cids-server + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..29abf999 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 00000000..dfa4f3ad --- /dev/null +++ b/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=true +org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations +org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..20b3c67b --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.processAnnotations=enabled +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 00000000..f897a7f1 --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..2f7f9a14 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,146 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Java", + "type": "java", + "request": "launch", + "stopOnEntry": true, + "jdkPath": "${env:JAVA_HOME}/bin", + "cwd": "${fileDirname}", + "startupClass": "${fileBasenameNoExtension}", + "classpath": [ + ".", + "${fileDirname}" + ] + }, + { + "name": "Java Console App", + "type": "java", + "request": "launch", + "stopOnEntry": true, + "jdkPath": "${env:JAVA_HOME}/bin", + "cwd": "${fileDirname}", + "startupClass": "${fileBasenameNoExtension}", + "classpath": [ + ".", + "${fileDirname}" + ], + "externalConsole": true + }, + { + "type": "java", + "name": "Debug (Launch) - Current File", + "request": "launch", + "mainClass": "${file}" + }, + { + "type": "java", + "name": "Debug (Launch)-TimedLoginRestriction", + "request": "launch", + "mainClass": "Sirius.server.localserver.user.TimedLoginRestriction", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-DomainServerImpl", + "request": "launch", + "mainClass": "Sirius.server.middleware.impls.domainserver.DomainServerImpl", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-RemoteTester", + "request": "launch", + "mainClass": "Sirius.server.middleware.impls.proxy.RemoteTester", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-StartProxy", + "request": "launch", + "mainClass": "Sirius.server.middleware.impls.proxy.StartProxy", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-UserServiceImpl", + "request": "launch", + "mainClass": "Sirius.server.middleware.impls.proxy.UserServiceImpl", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-Registry", + "request": "launch", + "mainClass": "Sirius.server.registry.Registry", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-RegistryMonitor", + "request": "launch", + "mainClass": "Sirius.server.registry.monitor.RegistryMonitor", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-DOMVersionChecker", + "request": "launch", + "mainClass": "Sirius.util.DBVersionChecker.DOMVersionChecker", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-NamingServerMonitor", + "request": "launch", + "mainClass": "Sirius.util.NamingServerMonitor.NamingServerMonitor", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-PortScan", + "request": "launch", + "mainClass": "Sirius.util.NamingServerMonitor.PortScan", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-NodeComparator", + "request": "launch", + "mainClass": "Sirius.util.NodeComparator", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-PreferencesTool", + "request": "launch", + "mainClass": "Sirius.util.PreferencesTool", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-ImageAnnotator", + "request": "launch", + "mainClass": "Sirius.util.image.ImageAnnotator", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-ConnectionContextBackend", + "request": "launch", + "mainClass": "de.cismet.cids.server.connectioncontext.ConnectionContextBackend", + "projectName": "cids-server" + }, + { + "type": "java", + "name": "Debug (Launch)-CidsBeanDeepPropertyListener", + "request": "launch", + "mainClass": "de.cismet.cids.utils.CidsBeanDeepPropertyListener", + "projectName": "cids-server" + } + ] +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 03894cac..27801375 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ de.cismet.cids cids-server-rest-types - 6.0 + 6.1-SNAPSHOT @@ -188,6 +188,42 @@ + + + io.jsonwebtoken + jjwt-api + 0.11.1 + + + io.jsonwebtoken + jjwt-impl + 0.11.1 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.1 + runtime + + + + org.bouncycastle + bcprov-jdk15on + 1.60 + runtime + + + + + + + + + + + + commons-beanutils commons-beanutils diff --git a/src/main/java/Sirius/server/localserver/_class/ClassCache.java b/src/main/java/Sirius/server/localserver/_class/ClassCache.java index a5e5ee68..52f7a294 100644 --- a/src/main/java/Sirius/server/localserver/_class/ClassCache.java +++ b/src/main/java/Sirius/server/localserver/_class/ClassCache.java @@ -319,6 +319,7 @@ public final List getAllClasses(final User u) { for (int i = 0; i < all.size(); i++) { final Class c = (Class)all.get(i); + if (c.getPermissions().hasReadPermission(u)) { cs.add(c); } diff --git a/src/main/java/Sirius/server/middleware/impls/proxy/UserServiceImpl.java b/src/main/java/Sirius/server/middleware/impls/proxy/UserServiceImpl.java index d3784347..01b8f299 100644 --- a/src/main/java/Sirius/server/middleware/impls/proxy/UserServiceImpl.java +++ b/src/main/java/Sirius/server/middleware/impls/proxy/UserServiceImpl.java @@ -20,15 +20,29 @@ import Sirius.server.newuser.UserGroup; import Sirius.server.newuser.UserServer; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.io.Encoders; +import io.jsonwebtoken.security.Keys; + import org.apache.log4j.Logger; import java.rmi.RemoteException; +import java.security.Key; + +import java.util.Base64; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + import de.cismet.connectioncontext.ConnectionContext; /** @@ -66,6 +80,32 @@ public UserServiceImpl(final Hashtable activeLocalServers, final UserServer user //~ Methods ---------------------------------------------------------------- + /** + * DOCUMENT ME! + * + * @param args DOCUMENT ME! + */ + public static void main(final String[] args) { + System.out.println("Will produce 20 random Secret Keys"); + for (int i = 0; i < 20; ++i) { + final SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256); + final String secretString = Encoders.BASE64.encode(key.getEncoded()); + System.out.println(secretString); + } + System.out.println("\nDecoding Test"); + final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; + + final byte[] decodedKey = Base64.getDecoder().decode("J0j+LcPz1I3ATqoi/QENz0dZD+C4pL6B9waw4zVw4e4="); + final Key serverKey = new SecretKeySpec(decodedKey, signatureAlgorithm.getJcaName()); + + final String secretString = Encoders.BASE64.encode(serverKey.getEncoded()); + System.out.println(secretString); + // .claim("usergroup", userGroupName+"@"+userGroupLsName) + final String jws = Jwts.builder().setId("1").setSubject("admin@s").signWith(serverKey).compact(); + System.out.println("\nJWS Test"); + System.out.println(jws); + } + /** * Wie konnte das jemals gehen Falsche Reihenfolge in Signatur public User getUser( String userLsName, String * userName, String userGroupLsName, String userGroupName, String password) throws RemoteException, UserException {. @@ -88,6 +128,10 @@ public User getUser(final String userGroupLsName, final String userName, final String password, final ConnectionContext context) throws RemoteException, UserException { + final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; + final byte[] decodedKey = Base64.getDecoder().decode("J0j+LcPz1I3ATqoi/QENz0dZD+C4pL6B9waw4zVw4e4="); + final Key serverKey = new SecretKeySpec(decodedKey, signatureAlgorithm.getJcaName()); + if (LOG.isDebugEnabled()) { LOG.debug("getUser calles for user::" + userName); // NOI18N @@ -97,35 +141,61 @@ public User getUser(final String userGroupLsName, // LOG.debug("userGroupName:" + userGroupName); // NOI18N LOG.debug((("password:" + password) == null) ? "null" : "*****"); // NOI18N } - final User u = userServer.getUser(userGroupLsName, userGroupName, userLsName, userName, password); - - boolean validated = false; - - if (u != null) { - final Sirius.server.middleware.interfaces.domainserver.UserService us = - (Sirius.server.middleware.interfaces.domainserver.UserService)activeLocalServers.get(userLsName); - - if (us != null) { - validated = us.validateUser(u, password, context); - } else { - throw new UserException( - "Login failed, home server of the user is not reachable :: " - + userName, // NOI18N - false, - false, - false, - true); + + final User u; + if (userName.equals("jwt")) { + final String jwt = password; + final Claims claims = Jwts.parserBuilder().setSigningKey(serverKey).build().parseClaimsJws(jwt).getBody(); + final int uid = new Integer(claims.getId()).intValue(); + final String jwtUsername = claims.getSubject(); + final String jwtDomain = claims.get("domain", String.class); + final String jwtUsergroup = claims.get("usergroup", String.class); + final String jwtUsergroupDomain = claims.get("usergroupDomain", String.class); + u = userServer.getUser(jwtUsergroupDomain, jwtUsergroup, jwtDomain, jwtUsername, "jwtCreatedUser"); + u.setValid(); + return u; + } else { +// + + u = userServer.getUser(userGroupLsName, userGroupName, userLsName, userName, password); + + boolean validated = false; + + if (u != null) { + final Sirius.server.middleware.interfaces.domainserver.UserService us = + (Sirius.server.middleware.interfaces.domainserver.UserService)activeLocalServers.get(userLsName); + + if (us != null) { + validated = us.validateUser(u, password, context); + } else { + throw new UserException( + "Login failed, home server of the user is not reachable :: " + + userName, // NOI18N + false, + false, + false, + true); + } } - } - if (validated) { - final String loginRestrictionValue = getConfigAttr(u, "login.restriction", context); - if (loginRestrictionValue != null) { - LoginRestrictionHelper.getInstance().checkLoginRestriction(loginRestrictionValue); + if (validated) { + final String loginRestrictionValue = getConfigAttr(u, "login.restriction", context); + if (loginRestrictionValue != null) { + LoginRestrictionHelper.getInstance().checkLoginRestriction(loginRestrictionValue); + } + + final JwtBuilder builder = Jwts.builder().setId(u.getId() + "").setSubject(userName); + builder.claim("domain", userLsName); + if ((userGroupName != null) && (userGroupLsName != null)) { + builder.claim("usergroup", userGroupName); + builder.claim("usergroupDomain", userGroupLsName); + } + + final String jws = builder.signWith(serverKey).compact(); + u.setJwsToken(jws); + return u; } - return u; } - throw new UserException("Login failed :: " + userName, false, true, false, false); // NOI18N } diff --git a/src/main/java/Sirius/server/newuser/User.java b/src/main/java/Sirius/server/newuser/User.java index 06f07c6d..2bc41a78 100644 --- a/src/main/java/Sirius/server/newuser/User.java +++ b/src/main/java/Sirius/server/newuser/User.java @@ -38,6 +38,8 @@ public class User implements java.io.Serializable, Mapable { protected boolean isAdmin = false; + protected String jwsToken = null; + //~ Constructors ----------------------------------------------------------- /** @@ -208,4 +210,22 @@ public Object constructKey(final Mapable m) { public int getId() { return id; } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public String getJwsToken() { + return jwsToken; + } + + /** + * DOCUMENT ME! + * + * @param jwsToken DOCUMENT ME! + */ + public void setJwsToken(final String jwsToken) { + this.jwsToken = jwsToken; + } }