Skip to content

Commit

Permalink
Java Auth Callout Example - working the compile 2
Browse files Browse the repository at this point in the history
  • Loading branch information
scottf committed Jan 9, 2024
1 parent 069fca5 commit 2d01fb1
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 181 deletions.
2 changes: 1 addition & 1 deletion docker/java/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM gradle:7.5.1-jdk8-jammy AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN mkdir -p src/main/java/example
RUN mv Main.java src/main/java/example/
RUN mv *.java src/main/java/example/
RUN gradle clean uberJar --no-daemon

FROM openjdk:8-jre-slim
Expand Down
144 changes: 144 additions & 0 deletions examples/auth/callout/java/AuthCalloutHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package example;

import io.nats.client.*;
import io.nats.client.impl.Headers;
import io.nats.jwt.*;
import io.nats.service.*;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import static io.nats.jwt.Utils.getClaimBody;

public class AuthCalloutHandler implements ServiceMessageHandler {
Connection nc;

public AuthCalloutHandler(Connection nc) {
this.nc = nc;
}

@Override
public void onMessage(ServiceMessage smsg) {
System.out.println("\nReceived Message");
System.out.println("Subject : " + smsg.getSubject());
System.out.println("Headers : " + headersToString(smsg.getHeaders()));

try {
// Convert the message data into a Claim
Claim claim = new Claim(getClaimBody(smsg.getData()));
System.out.println("Claim-Request : " + claim.toJson());

// The Claim should contain an Authorization Request
AuthorizationRequest ar = claim.authorizationRequest;
if (ar == null) {
System.err.println("Invalid Authorization Request Claim");
return;
}
printJson("Auth Request : ", ar.toJson(), "server_id", "user_nkey", "client_info", "connect_opts", "client_tls", "request_nonce");

// Check if the user exists.
AuthCalloutUser acUser = NATS_USERS.get(ar.connectOpts.user);
if (acUser == null) {
respond(smsg, ar, null, "User Not Found: " + ar.connectOpts.user);
return;
}
if (!acUser.pass.equals(ar.connectOpts.pass)) {
respond(smsg, ar, null, "Password does not match: " + acUser.pass + " != " + ar.connectOpts.pass);
return;
}

UserClaim uc = new UserClaim()
.pub(acUser.pub)
.sub(acUser.sub)
.resp(acUser.resp);

String userJwt = new ClaimIssuer()
.aud(acUser.account)
.name(ar.connectOpts.user)
.iss(PUB_USER_SIGNING_KEY)
.sub(ar.userNkey)
.nats(uc)
.issueJwt(USER_SIGNING_KEY);

respond(smsg, ar, userJwt, null);
}
catch (Exception e) {
e.printStackTrace()(e);
}
}

private void respond(ServiceMessage smsg,
AuthorizationRequest ar,
String userJwt,
String error) throws GeneralSecurityException, IOException {

AuthorizationResponse response = new AuthorizationResponse()
.jwt(userJwt)
.error(error);

if (userJwt != null) {
printJson("Auth Resp JWT : ", getClaimBody(userJwt), "name", "nats");
}
else {
System.out.println("Auth Resp ERR : " + response.toJson());
}

String jwt = new ClaimIssuer()
.aud(ar.serverId.id)
.iss(PUB_USER_SIGNING_KEY)
.sub(ar.userNkey)
.nats(response)
.issueJwt(USER_SIGNING_KEY);

System.out.println("Claim-Response: " + getClaimBody(jwt));
smsg.respond(nc, jwt);
}

static final String SPACER = " ";
static void printJson(String label, String json, String... splits) {
if (splits != null && splits.length > 0) {
String indent = SPACER.substring(0, label.length());
boolean first = true;
for (String split : splits) {
int at = json.indexOf("\"" + split + "\"");
if (at > 0) {
if (first) {
first = false;
System.out.println(label + json.substring(0, at));
}
else {
System.out.println(indent + json.substring(0, at));
}
json = json.substring(at);
}
}
System.out.println(indent + json);
}
else {
System.out.println(label + json);
}
}

static String headersToString(Headers h) {
if (h == null || h.isEmpty()) {
return "None";
}

boolean notFirst = false;
StringBuilder sb = new StringBuilder("[");
for (String key : h.keySet()) {
if (notFirst) {
sb.append(',');
}
else {
notFirst = true;
}
sb.append(key).append("=").append(h.get(key));
}
return sb.append(']').toString();
}
}
49 changes: 49 additions & 0 deletions examples/auth/callout/java/AuthCalloutUser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package example;

import io.nats.jwt.Permission;
import io.nats.jwt.ResponsePermission;

public class AuthCalloutUser {
public String user;
public String pass;
public String account;
public Permission pub;
public Permission sub;
public ResponsePermission resp;

public AuthCalloutUser userPass(String userPass) {
this.user = userPass;
this.pass = userPass;
return this;
}

public AuthCalloutUser user(String user) {
this.user = user;
return this;
}

public AuthCalloutUser pass(String pass) {
this.pass = pass;
return this;
}

public AuthCalloutUser account(String account) {
this.account = account;
return this;
}

public AuthCalloutUser pub(Permission pub) {
this.pub = pub;
return this;
}

public AuthCalloutUser sub(Permission sub) {
this.sub = sub;
return this;
}

public AuthCalloutUser resp(ResponsePermission resp) {
this.resp = resp;
return this;
}
}
181 changes: 1 addition & 180 deletions examples/auth/callout/java/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,186 +87,7 @@ public static void main(String[] args) throws Exception {
// serviceStoppedFuture.get();
}
catch (Exception e) {
onException(e);
}
}

static class AuthCalloutHandler implements ServiceMessageHandler {
Connection nc;

public AuthCalloutHandler(Connection nc) {
this.nc = nc;
}

@Override
public void onMessage(ServiceMessage smsg) {
System.out.println("\nReceived Message");
System.out.println("Subject : " + smsg.getSubject());
System.out.println("Headers : " + headersToString(smsg.getHeaders()));

try {
// Convert the message data into a Claim
Claim claim = new Claim(getClaimBody(smsg.getData()));
System.out.println("Claim-Request : " + claim.toJson());

// The Claim should contain an Authorization Request
AuthorizationRequest ar = claim.authorizationRequest;
if (ar == null) {
System.err.println("Invalid Authorization Request Claim");
return;
}
printJson("Auth Request : ", ar.toJson(), "server_id", "user_nkey", "client_info", "connect_opts", "client_tls", "request_nonce");

// Check if the user exists.
AuthCalloutUser acUser = NATS_USERS.get(ar.connectOpts.user);
if (acUser == null) {
respond(smsg, ar, null, "User Not Found: " + ar.connectOpts.user);
return;
}
if (!acUser.pass.equals(ar.connectOpts.pass)) {
respond(smsg, ar, null, "Password does not match: " + acUser.pass + " != " + ar.connectOpts.pass);
return;
}

UserClaim uc = new UserClaim()
.pub(acUser.pub)
.sub(acUser.sub)
.resp(acUser.resp);

String userJwt = new ClaimIssuer()
.aud(acUser.account)
.name(ar.connectOpts.user)
.iss(PUB_USER_SIGNING_KEY)
.sub(ar.userNkey)
.nats(uc)
.issueJwt(USER_SIGNING_KEY);

respond(smsg, ar, userJwt, null);
}
catch (Exception e) {
onException(e);
}
}

static final String SPACER = " ";
private void printJson(String label, String json, String... splits) {
if (splits != null && splits.length > 0) {
String indent = SPACER.substring(0, label.length());
boolean first = true;
for (String split : splits) {
int at = json.indexOf("\"" + split + "\"");
if (at > 0) {
if (first) {
first = false;
System.out.println(label + json.substring(0, at));
}
else {
System.out.println(indent + json.substring(0, at));
}
json = json.substring(at);
}
}
System.out.println(indent + json);
}
else {
System.out.println(label + json);
}
}

private void respond(ServiceMessage smsg,
AuthorizationRequest ar,
String userJwt,
String error) throws GeneralSecurityException, IOException {

AuthorizationResponse response = new AuthorizationResponse()
.jwt(userJwt)
.error(error);

if (userJwt != null) {
printJson("Auth Resp JWT : ", getClaimBody(userJwt), "name", "nats");
}
else {
System.out.println("Auth Resp ERR : " + response.toJson());
}

String jwt = new ClaimIssuer()
.aud(ar.serverId.id)
.iss(PUB_USER_SIGNING_KEY)
.sub(ar.userNkey)
.nats(response)
.issueJwt(USER_SIGNING_KEY);

System.out.println("Claim-Response: " + getClaimBody(jwt));
smsg.respond(nc, jwt);
}
}

private static void onException(Exception e) {
//noinspection CallToPrintStackTrace
e.printStackTrace();
}

public static String headersToString(Headers h) {
if (h == null || h.isEmpty()) {
return "None";
}

boolean notFirst = false;
StringBuilder sb = new StringBuilder("[");
for (String key : h.keySet()) {
if (notFirst) {
sb.append(',');
}
else {
notFirst = true;
}
sb.append(key).append("=").append(h.get(key));
}
return sb.append(']').toString();
}

static class AuthCalloutUser {
public String user;
public String pass;
public String account;
public Permission pub;
public Permission sub;
public ResponsePermission resp;

public AuthCalloutUser userPass(String userPass) {
this.user = userPass;
this.pass = userPass;
return this;
}

public AuthCalloutUser user(String user) {
this.user = user;
return this;
}

public AuthCalloutUser pass(String pass) {
this.pass = pass;
return this;
}

public AuthCalloutUser account(String account) {
this.account = account;
return this;
}

public AuthCalloutUser pub(Permission pub) {
this.pub = pub;
return this;
}

public AuthCalloutUser sub(Permission sub) {
this.sub = sub;
return this;
}

public AuthCalloutUser resp(ResponsePermission resp) {
this.resp = resp;
return this;
e.printStackTrace();
}
}
}
Expand Down

0 comments on commit 2d01fb1

Please sign in to comment.