From ee8cfdacfbaf1bc1d41011000cb4345b4493c850 Mon Sep 17 00:00:00 2001 From: dudash Date: Tue, 21 Apr 2020 21:36:17 -0400 Subject: [PATCH 1/3] adding authorization --- README.md | 10 +++++++ src/main/java/io/nub3s/ScoresResource.java | 31 ++++++++++++++++++++-- src/main/resources/application.properties | 10 +++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b3a39b2..151daad 100644 --- a/README.md +++ b/README.md @@ -90,5 +90,15 @@ This service won't function until it can store its data into a MongoDB. We can e ## Hooking in 3scale API Management TBD - [3scale ref here](https://access.redhat.com/documentation/en-us/red_hat_3scale_api_management/2.7/html/providing_apis_in_the_developer_portal/create-new-service-openapi-specification#using_openapi_specification) + +## Testing POSTS with HTTPie +I like to use a nice CLI tool called HTTPie. If you have it below are some useful commands. + +### Testing POST with basic auth turned on +``` +http -a jason:password POST http://localhost:5000/scores score=1000 name=JAS +``` + + ## Thanks and Credit This service was built based on guidance from the [Quarkus example here](https://quarkus.io/guides/openapi-swaggerui#loading-openapi-schema-from-static-files). diff --git a/src/main/java/io/nub3s/ScoresResource.java b/src/main/java/io/nub3s/ScoresResource.java index f08bf55..117d647 100644 --- a/src/main/java/io/nub3s/ScoresResource.java +++ b/src/main/java/io/nub3s/ScoresResource.java @@ -1,20 +1,32 @@ package io.nub3s; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import io.vertx.axle.core.eventbus.EventBus; -import io.vertx.axle.core.eventbus.Message; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; + +import org.eclipse.microprofile.config.inject.ConfigProperty; + import java.util.List; @Path("/scores") public class ScoresResource { + @ConfigProperty(name = "quickauthenforcing", defaultValue = "true") + protected boolean quickAuthEnforcing; + @ConfigProperty(name = "quickauthuser", defaultValue = "true") + protected String quickAuthUser; + @ConfigProperty(name = "quickauthpassword", defaultValue = "true") + protected String quickAuthPassword; + @Inject EventBus bus; @GET @@ -25,7 +37,22 @@ public List list(){ @POST @Consumes("application/json") - public Response create(Score score) { + public Response create(@HeaderParam("Authorization") String authorization, Score score) { + if (quickAuthEnforcing) { + if (authorization == null) return Response.status(401).build(); + if (!authorization.toLowerCase().startsWith("basic")) return Response.status(401).build(); + String base64string = authorization.substring("Basic".length()).trim(); + byte[] bytes = Base64.getDecoder().decode(base64string); + String credentials = new String(bytes, StandardCharsets.UTF_8); + final String[] keyValueCredentials = credentials.split(":", 2); + System.out.println("GOT USER=" + keyValueCredentials[0].compareTo(quickAuthUser)); + System.out.println("GOT PASSWORD=" + keyValueCredentials[1].compareTo(quickAuthPassword)); + if (keyValueCredentials[0].compareTo(quickAuthUser)!=0) return Response.status(401).build(); + if (keyValueCredentials[1].compareTo(quickAuthPassword)!=0) return Response.status(401).build(); + } + else { + System.out.println("ignoring auth"); + } score.persist(); bus.publish("newscore", score.toString()); // tell NotifcationsWebSocket to broadcast an update bus.publish("topten", topTenList().toString()); // tell NotifcationsWebSocket to broadcast an update diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a205bdc..fed38b1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -2,6 +2,16 @@ quarkus.http.port=8080 %dev.quarkus.http.port=5000 +# Security +quickauthenforcing=${QUICKAUTH_ENFORCING:true} +quickauthuser=${QUICKAUTH_USER:dudash} +quickauthpassword=${QUICKAUTH_PASSWORD:123456} +# TODO: Auth should be done with an IdentityProvider and vars below +# quarkus.http.auth.basic=true +# quarkus.http.auth.permission.api-permission-check1.paths=/scores +# quarkus.http.auth.permission.api-permission-check1.policy=authenticated +# quarkus.http.auth.permission.api-permission-check1.methods=POST + # API Stuff # if doing a demo app, turn this on - make default off for security reasons quarkus.swagger-ui.always-include=false From c336fce4fff0b8bfae10ecfc3cab14d4fb31d009 Mon Sep 17 00:00:00 2001 From: dudash Date: Tue, 21 Apr 2020 21:39:48 -0400 Subject: [PATCH 2/3] updating readme and setting default dev env to not use auth --- README.md | 6 +++++- src/main/resources/application.properties | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 151daad..e24ab86 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,10 @@ Expose access to outside of cluster For more info on this way of deploying (and alternatives) [see the docs here](https://quarkus.io/guides/deploying-to-openshift-s2i). ## Other Things +## The POST route for scores now has basic auth enabled on it +* So you will need to pass username/password in to POST scores +* You can disable it with an environment vairable (see the application.properties file) + ## Running a MongoDB in OpenShift This service won't function until it can store its data into a MongoDB. We can easily deploy one on OpenShift and have OpenShift provide service discovery. And then we configure this app's deployment with the user/password details for connecting to the DB. > `oc new-app -e MONGODB_USER=thisisauser -e MONGODB_PASSWORD=thisis4password -e MONGODB_DATABASE=highscores -e MONGODB_ADMIN_PASSWORD=thisis4password mongodb:latest` @@ -96,7 +100,7 @@ I like to use a nice CLI tool called HTTPie. If you have it below are some usefu ### Testing POST with basic auth turned on ``` -http -a jason:password POST http://localhost:5000/scores score=1000 name=JAS +http -a dudash:123456 POST http://localhost:5000/scores score=1000 name=JAS ``` diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index fed38b1..5eb38d3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -3,6 +3,7 @@ quarkus.http.port=8080 %dev.quarkus.http.port=5000 # Security +%dev.quickauthenforcing=false quickauthenforcing=${QUICKAUTH_ENFORCING:true} quickauthuser=${QUICKAUTH_USER:dudash} quickauthpassword=${QUICKAUTH_PASSWORD:123456} From ef1820c610712ec2f338442c2d78d9c423c4fbb8 Mon Sep 17 00:00:00 2001 From: dudash Date: Tue, 21 Apr 2020 21:42:03 -0400 Subject: [PATCH 3/3] removing printlines --- src/main/java/io/nub3s/ScoresResource.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/io/nub3s/ScoresResource.java b/src/main/java/io/nub3s/ScoresResource.java index 117d647..adb1654 100644 --- a/src/main/java/io/nub3s/ScoresResource.java +++ b/src/main/java/io/nub3s/ScoresResource.java @@ -45,8 +45,6 @@ public Response create(@HeaderParam("Authorization") String authorization, Score byte[] bytes = Base64.getDecoder().decode(base64string); String credentials = new String(bytes, StandardCharsets.UTF_8); final String[] keyValueCredentials = credentials.split(":", 2); - System.out.println("GOT USER=" + keyValueCredentials[0].compareTo(quickAuthUser)); - System.out.println("GOT PASSWORD=" + keyValueCredentials[1].compareTo(quickAuthPassword)); if (keyValueCredentials[0].compareTo(quickAuthUser)!=0) return Response.status(401).build(); if (keyValueCredentials[1].compareTo(quickAuthPassword)!=0) return Response.status(401).build(); }