jwt login

This commit is contained in:
Yannick Bour 2023-02-23 15:48:32 +01:00 committed by jeffcheasey88
parent fd66010226
commit cfe9d83d2c
11 changed files with 94 additions and 88 deletions

View file

@ -132,4 +132,4 @@ public class Configuration {
public boolean useSsl(){ public boolean useSsl(){
return this.use_ssl; return this.use_ssl;
} }
} }

View file

@ -12,13 +12,20 @@ import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.PublicJsonWebKey;
import org.jose4j.jwk.RsaJsonWebKey; import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jwk.RsaJwkGenerator; import org.jose4j.jwk.RsaJwkGenerator;
import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature; import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims; import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.ErrorCodes;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.lang.JoseException;
import be.jeffcheasey88.peeratcode.model.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.routes.ChapterElement; import be.jeffcheasey88.peeratcode.routes.ChapterElement;
import be.jeffcheasey88.peeratcode.routes.ChapterList; import be.jeffcheasey88.peeratcode.routes.ChapterList;
@ -32,12 +39,81 @@ import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
import be.jeffcheasey88.peeratcode.webserver.HttpWriter; import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
import be.jeffcheasey88.peeratcode.webserver.Response; import be.jeffcheasey88.peeratcode.webserver.Response;
import be.jeffcheasey88.peeratcode.webserver.Router; import be.jeffcheasey88.peeratcode.webserver.Router;
import be.jeffcheasey88.peeratcode.webserver.User;
public class Main { public class Main {
// Define SSL Protocol parameters // Define SSL Protocol parameters
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Configuration config = new Configuration("config.txt"); Configuration config = new Configuration("config.txt");
config.load(); config.load();
/*try
{
JwtClaims claims = new JwtClaims();
claims.setIssuer("Issuer"); // who creates the token and signs it
claims.setAudience("Audience"); // to whom the token is intended to be sent
claims.setExpirationTimeMinutesInTheFuture(10); // time when the token will expire (10 minutes from now)
claims.setGeneratedJwtId(); // a unique identifier for the token
claims.setIssuedAtToNow(); // when the token was issued/created (now)
claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago)
claims.setClaim("username","USERNAME");
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setKey(rsaJsonWebKey.getPrivateKey());
jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId());
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
String jwt = jws.getCompactSerialization();
System.out.println("jwt token = " + jwt);
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account for clock skew
.setRequireSubject() // the JWT must have a subject claim
.setExpectedIssuer("Issuer") // whom the JWT needs to have been issued by
.setExpectedAudience("Audience") // to whom the JWT is intended for
.setVerificationKey(rsaJsonWebKey.getKey()) // verify the signature with the public key
.setJwsAlgorithmConstraints( // only allow the expected signature algorithm(s) in the given context
ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256) // which is only RS256 here
.build(); // create the JwtConsumer instance
// Validate the JWT and process it to the Claims
JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
System.out.println("JWT validation = " + jwtClaims);
}
catch (InvalidJwtException e)
{
// InvalidJwtException will be thrown, if the JWT failed processing or validation in anyway.
// Hopefully with meaningful explanations(s) about what went wrong.
System.out.println("Invalid JWT! " + e);
// Programmatic access to (some) specific reasons for JWT invalidity is also possible
// should you want different error handling behavior for certain conditions.
// Whether or not the JWT has expired being one common reason for invalidity
if (e.hasExpired())
{
System.out.println("JWT expired");
}
// Or maybe the audience was invalid
if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID))
{
System.out.println("JWT had wrong audience");
}
} catch (JoseException e) {
e.printStackTrace();
}*/
Class.forName("com.mysql.cj.jdbc.Driver"); Class.forName("com.mysql.cj.jdbc.Driver");
Router router = new Router(); Router router = new Router();
@ -84,7 +160,7 @@ public class Main {
while (!server.isClosed()) { while (!server.isClosed()) {
Socket socket = server.accept(); Socket socket = server.accept();
Client client = new Client(socket, router); Client client = new Client(socket, router, RsaJwkGenerator.generateJwk(2048));
client.start(); client.start();
} }
} catch (Exception e) { } catch (Exception e) {
@ -99,7 +175,8 @@ public class Main {
try (ServerSocket server = new ServerSocket(config.getTcpPort())){ try (ServerSocket server = new ServerSocket(config.getTcpPort())){
while(!server.isClosed()){ while(!server.isClosed()){
Socket socket = server.accept(); Socket socket = server.accept();
Client client = new Client(socket, router); RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
Client client = new Client(socket, router, rsaJsonWebKey);
client.start(); client.start();
} }
} }

View file

@ -1,71 +0,0 @@
package be.jeffcheasey88.peeratcode.model;
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.ErrorCodes;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
public class User {
private final String username;
public User(String jwt) {
new RsaJsonWebKey();
// Use JwtConsumerBuilder to construct an appropriate JwtConsumer, which will
// be used to validate and process the JWT.
// The specific validation requirements for a JWT are context dependent, however,
// it is typically advisable to require a (reasonable) expiration time, a trusted issuer, and
// an audience that identifies your system as the intended recipient.
// If the JWT is encrypted too, you need only provide a decryption key or
// decryption key resolver to the builder.
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account for clock skew
.setRequireSubject() // the JWT must have a subject claim
.setExpectedIssuer("Issuer") // whom the JWT needs to have been issued by
.setExpectedAudience("Audience") // to whom the JWT is intended for
.setVerificationKey(rsaJsonWebKey.getKey()) // verify the signature with the public key
.setJwsAlgorithmConstraints( // only allow the expected signature algorithm(s) in the given context
ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256) // which is only RS256 here
.build(); // create the JwtConsumer instance
try
{
// Validate the JWT and process it to the Claims
JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
System.out.println("JWT validation succeeded! " + jwtClaims);
}
catch (InvalidJwtException e)
{
// InvalidJwtException will be thrown, if the JWT failed processing or validation in anyway.
// Hopefully with meaningful explanations(s) about what went wrong.
System.out.println("Invalid JWT! " + e);
// Programmatic access to (some) specific reasons for JWT invalidity is also possible
// should you want different error handling behavior for certain conditions.
// Whether or not the JWT has expired being one common reason for invalidity
if (e.hasExpired())
{
System.out.println("JWT expired at " + e.getJwtContext().getJwtClaims().getExpirationTime());
}
// Or maybe the audience was invalid
if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID))
{
System.out.println("JWT had wrong audience: " + e.getJwtContext().getJwtClaims().getAudience());
}
}
this.username = username;
}
public String getUsername() {
return username;
}
}

View file

@ -2,12 +2,13 @@ package be.jeffcheasey88.peeratcode.routes;
import be.jeffcheasey88.peeratcode.model.Chapter; import be.jeffcheasey88.peeratcode.model.Chapter;
import be.jeffcheasey88.peeratcode.model.Puzzle; import be.jeffcheasey88.peeratcode.model.Puzzle;
import be.jeffcheasey88.peeratcode.model.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.webserver.HttpReader; import be.jeffcheasey88.peeratcode.webserver.HttpReader;
import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
import be.jeffcheasey88.peeratcode.webserver.HttpWriter; import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
import be.jeffcheasey88.peeratcode.webserver.Response; import be.jeffcheasey88.peeratcode.webserver.Response;
import be.jeffcheasey88.peeratcode.webserver.User;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;

View file

@ -1,12 +1,13 @@
package be.jeffcheasey88.peeratcode.routes; package be.jeffcheasey88.peeratcode.routes;
import be.jeffcheasey88.peeratcode.model.Chapter; import be.jeffcheasey88.peeratcode.model.Chapter;
import be.jeffcheasey88.peeratcode.model.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.webserver.HttpReader; import be.jeffcheasey88.peeratcode.webserver.HttpReader;
import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
import be.jeffcheasey88.peeratcode.webserver.HttpWriter; import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
import be.jeffcheasey88.peeratcode.webserver.Response; import be.jeffcheasey88.peeratcode.webserver.Response;
import be.jeffcheasey88.peeratcode.webserver.User;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;

View file

@ -5,12 +5,12 @@ import java.util.regex.Pattern;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.model.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.webserver.HttpReader; import be.jeffcheasey88.peeratcode.webserver.HttpReader;
import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
import be.jeffcheasey88.peeratcode.webserver.HttpWriter; import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
import be.jeffcheasey88.peeratcode.webserver.Response; import be.jeffcheasey88.peeratcode.webserver.Response;
import be.jeffcheasey88.peeratcode.webserver.User;
public class Login implements Response { public class Login implements Response {

View file

@ -7,12 +7,12 @@ import java.util.regex.Pattern;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.model.Puzzle; import be.jeffcheasey88.peeratcode.model.Puzzle;
import be.jeffcheasey88.peeratcode.model.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.webserver.HttpReader; import be.jeffcheasey88.peeratcode.webserver.HttpReader;
import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
import be.jeffcheasey88.peeratcode.webserver.HttpWriter; import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
import be.jeffcheasey88.peeratcode.webserver.Response; import be.jeffcheasey88.peeratcode.webserver.Response;
import be.jeffcheasey88.peeratcode.webserver.User;
public class PuzzleElement implements Response { public class PuzzleElement implements Response {

View file

@ -5,12 +5,12 @@ import java.util.regex.Pattern;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.model.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.webserver.HttpReader; import be.jeffcheasey88.peeratcode.webserver.HttpReader;
import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
import be.jeffcheasey88.peeratcode.webserver.HttpWriter; import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
import be.jeffcheasey88.peeratcode.webserver.Response; import be.jeffcheasey88.peeratcode.webserver.Response;
import be.jeffcheasey88.peeratcode.webserver.User;
public class Register implements Response { public class Register implements Response {

View file

@ -3,20 +3,22 @@ package be.jeffcheasey88.peeratcode.webserver;
import java.net.Socket; import java.net.Socket;
import java.util.Arrays; import java.util.Arrays;
import be.jeffcheasey88.peeratcode.model.User; import org.jose4j.jwk.RsaJsonWebKey;
public class Client extends Thread{ public class Client extends Thread{
private HttpReader reader; private HttpReader reader;
private HttpWriter writer; private HttpWriter writer;
private Router router; private Router router;
private RsaJsonWebKey key;
public Client(Socket socket, Router router) throws Exception{ public Client(Socket socket, Router router, RsaJsonWebKey key) throws Exception{
this.reader = new HttpReader(socket); this.reader = new HttpReader(socket);
this.writer = new HttpWriter(socket); this.writer = new HttpWriter(socket);
this.router = router; this.router = router;
this.key = key;
} }
@Override @Override
public void run(){ public void run(){
try { try {

View file

@ -3,8 +3,6 @@ package be.jeffcheasey88.peeratcode.webserver;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import be.jeffcheasey88.peeratcode.model.User;
public interface Response{ public interface Response{
void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception ; void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception ;

View file

@ -4,8 +4,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import be.jeffcheasey88.peeratcode.model.User;
public class Router{ public class Router{
private List<Response> responses; private List<Response> responses;