Skip to content

Commit

Permalink
feat: use RS256 to sign JWT token (#17)
Browse files Browse the repository at this point in the history
Signed-off-by: Yixiang Zhao <[email protected]>
  • Loading branch information
seriouszyx authored Feb 8, 2022
1 parent 0ef1f05 commit bab83d6
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ hs_err_pid*

.idea/
*.iml

target
2 changes: 1 addition & 1 deletion src/main/java/org/casbin/casdoor/config/CasdoorConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class CasdoorConfig {
private String endpoint;
private String clientId;
private String clientSecret;
private String jwtSecret;
private String jwtPublicKey;
private String organizationName;
private String applicationName;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class CasdoorException extends Exception {

public static CasdoorException NETWORK_EXCEPTION = new CasdoorException("Connection timeout.");
public static CasdoorException ENDPOINT_EXCEPTION = new CasdoorException("Unknown response data structure from endpoint. Please check whether the endpoint is a Casdoor instance, and is the same version of the SDK.");
public static CasdoorException PARSE_JWT_TOKEN_EXCEPTION = new CasdoorException("Cannot parse jwt token.");
public static CasdoorException VERIFY_JWT_PUBLIC_KEY_EXCEPTION = new CasdoorException("Cannot verify signature.");

private CasdoorException(String reason) {
super(reason);
Expand Down
40 changes: 36 additions & 4 deletions src/main/java/org/casbin/casdoor/service/CasdoorAuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

package org.casbin.casdoor.service;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.SignedJWT;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.oltu.oauth2.client.OAuthClient;
Expand All @@ -26,11 +29,17 @@
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.casbin.casdoor.config.CasdoorConfig;
import org.casbin.casdoor.entity.CasdoorUser;
import org.casbin.casdoor.exception.CasdoorException;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
import java.util.Map;

Expand All @@ -56,11 +65,34 @@ public String getOAuthToken(String code, String state) throws OAuthSystemExcepti
return oAuthResponse.getAccessToken();
}

public CasdoorUser parseJwtToken(String token) throws ParseException, InvocationTargetException, IllegalAccessException {
SignedJWT parseJWT = SignedJWT.parse(token);
Map<String, Object> claims = parseJWT.getJWTClaimsSet().getClaims();
public CasdoorUser parseJwtToken(String token) throws CasdoorException, InvocationTargetException, IllegalAccessException {
// parse jwt token
SignedJWT parseJWT = null;
Map<String, Object> claims = null;
try {
parseJWT = SignedJWT.parse(token);
claims = parseJWT.getJWTClaimsSet().getClaims();
} catch (ParseException e) {
throw CasdoorException.PARSE_JWT_TOKEN_EXCEPTION;
}

// verify the jwt public key
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(casdoorConfig.getJwtPublicKey().getBytes()));
RSAPublicKey publicKey = (RSAPublicKey) cert.getPublicKey();
JWSVerifier verifier = new RSASSAVerifier(publicKey);
boolean verify = parseJWT.verify(verifier);
if (!verify) {
throw CasdoorException.VERIFY_JWT_PUBLIC_KEY_EXCEPTION;
}
} catch (CertificateException | JOSEException e) {
throw CasdoorException.VERIFY_JWT_PUBLIC_KEY_EXCEPTION;
}

// convert to CasdoorUser
CasdoorUser casdoorUser = new CasdoorUser();
BeanUtils.copyProperties(casdoorUser,claims);
BeanUtils.copyProperties(casdoorUser, claims);
return casdoorUser;
}

Expand Down
43 changes: 40 additions & 3 deletions src/main/test/java/org/casbin/casdoor/CasdoorAuthServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.casbin.casdoor.config.CasdoorConfig;
import org.casbin.casdoor.entity.CasdoorUser;
import org.casbin.casdoor.exception.CasdoorException;
import org.casbin.casdoor.service.CasdoorAuthService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;

public class CasdoorAuthServiceTest {

Expand All @@ -26,19 +27,55 @@ public void initConfig() {
"http://localhost:8000",
"f485cd52dab369c8551a",
"1d7221b217ed3d12100da5e208aa93c8770e4a81",
"CasdoorSecret",
"-----BEGIN CERTIFICATE-----\n" +
"MIIE+TCCAuGgAwIBAgIDAeJAMA0GCSqGSIb3DQEBCwUAMDYxHTAbBgNVBAoTFENh\n" +
"c2Rvb3IgT3JnYW5pemF0aW9uMRUwEwYDVQQDEwxDYXNkb29yIENlcnQwHhcNMjEx\n" +
"MDE1MDgxMTUyWhcNNDExMDE1MDgxMTUyWjA2MR0wGwYDVQQKExRDYXNkb29yIE9y\n" +
"Z2FuaXphdGlvbjEVMBMGA1UEAxMMQ2FzZG9vciBDZXJ0MIICIjANBgkqhkiG9w0B\n" +
"AQEFAAOCAg8AMIICCgKCAgEAsInpb5E1/ym0f1RfSDSSE8IR7y+lw+RJjI74e5ej\n" +
"rq4b8zMYk7HeHCyZr/hmNEwEVXnhXu1P0mBeQ5ypp/QGo8vgEmjAETNmzkI1NjOQ\n" +
"CjCYwUrasO/f/MnI1C0j13vx6mV1kHZjSrKsMhYY1vaxTEP3+VB8Hjg3MHFWrb07\n" +
"uvFMCJe5W8+0rKErZCKTR8+9VB3janeBz//zQePFVh79bFZate/hLirPK0Go9P1g\n" +
"OvwIoC1A3sarHTP4Qm/LQRt0rHqZFybdySpyWAQvhNaDFE7mTstRSBb/wUjNCUBD\n" +
"PTSLVjC04WllSf6Nkfx0Z7KvmbPstSj+btvcqsvRAGtvdsB9h62Kptjs1Yn7GAuo\n" +
"I3qt/4zoKbiURYxkQJXIvwCQsEftUuk5ew5zuPSlDRLoLByQTLbx0JqLAFNfW3g/\n" +
"pzSDjgd/60d6HTmvbZni4SmjdyFhXCDb1Kn7N+xTojnfaNkwep2REV+RMc0fx4Gu\n" +
"hRsnLsmkmUDeyIZ9aBL9oj11YEQfM2JZEq+RVtUx+wB4y8K/tD1bcY+IfnG5rBpw\n" +
"IDpS262boq4SRSvb3Z7bB0w4ZxvOfJ/1VLoRftjPbLIf0bhfr/AeZMHpIKOXvfz4\n" +
"yE+hqzi68wdF0VR9xYc/RbSAf7323OsjYnjjEgInUtRohnRgCpjIk/Mt2Kt84Kb0\n" +
"wn8CAwEAAaMQMA4wDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAn2lf\n" +
"DKkLX+F1vKRO/5gJ+Plr8P5NKuQkmwH97b8CS2gS1phDyNgIc4/LSdzuf4Awe6ve\n" +
"C06lVdWSIis8UPUPdjmT2uMPSNjwLxG3QsrimMURNwFlLTfRem/heJe0Zgur9J1M\n" +
"8haawdSdJjH2RgmFoDeE2r8NVRfhbR8KnCO1ddTJKuS1N0/irHz21W4jt4rxzCvl\n" +
"2nR42Fybap3O/g2JXMhNNROwZmNjgpsF7XVENCSuFO1jTywLaqjuXCg54IL7XVLG\n" +
"omKNNNcc8h1FCeKj/nnbGMhodnFWKDTsJcbNmcOPNHo6ixzqMy/Hqc+mWYv7maAG\n" +
"Jtevs3qgMZ8F9Qzr3HpUc6R3ZYYWDY/xxPisuKftOPZgtH979XC4mdf0WPnOBLqL\n" +
"2DJ1zaBmjiGJolvb7XNVKcUfDXYw85ZTZQ5b9clI4e+6bmyWqQItlwt+Ati/uFEV\n" +
"XzCj70B4lALX6xau1kLEpV9O1GERizYRz5P9NJNA7KoO5AVMp9w0DQTkt+LbXnZE\n" +
"HHnWKy8xHQKZF9sR7YBPGLs/Ac6tviv5Ua15OgJ/8dLRZ/veyFfGo2yZsI+hKVU5\n" +
"nCCJHBcAyFnm1hdvdwEdH33jDBjNB6ciotJZrf/3VYaIWSalADosHAgMWfXuWP+h\n" +
"8XKXmzlxuHbTMQYtZPDgspS5aK+S4Q9wb8RRAYo=\n" +
"-----END CERTIFICATE-----",
"built-in",
"app-built-in"
);
}

@Test
public void testAuthService() throws OAuthProblemException, OAuthSystemException, ParseException, InvocationTargetException, IllegalAccessException {
public void testAuthService() throws OAuthProblemException, OAuthSystemException, CasdoorException, InvocationTargetException, IllegalAccessException {
String code = "71b645e73381caeb2c66";
CasdoorAuthService casdoorAuthService = new CasdoorAuthService(this.casdoorConfig);
String token = casdoorAuthService.getOAuthToken(code, "app-built-in");
Assert.assertNotNull(token);
CasdoorUser casdoorUser = casdoorAuthService.parseJwtToken(token);
Assert.assertNotNull(casdoorUser);
}

@Test
public void testGetSigninUel() throws UnsupportedEncodingException {
CasdoorAuthService casdoorAuthService = new CasdoorAuthService(this.casdoorConfig);
String signinUrl = casdoorAuthService.getSigninUrl("http://localhost:3000/callback");
System.out.println(signinUrl);
Assert.assertNotEquals("", signinUrl);
}
}

0 comments on commit bab83d6

Please sign in to comment.