Auth ok
This commit is contained in:
@@ -8,6 +8,9 @@ import org.jeudego.pairgoth.util.AESCryptograph
|
|||||||
import org.jeudego.pairgoth.util.Cryptograph
|
import org.jeudego.pairgoth.util.Cryptograph
|
||||||
import org.jeudego.pairgoth.util.Randomizer
|
import org.jeudego.pairgoth.util.Randomizer
|
||||||
import org.jeudego.pairgoth.web.sharedSecret
|
import org.jeudego.pairgoth.web.sharedSecret
|
||||||
|
import org.jeudego.pairgoth.web.toHex
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.security.MessageDigest
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
@@ -18,6 +21,7 @@ object TokenHandler: ApiHandler {
|
|||||||
const val AUTH_HEADER = "Authorization"
|
const val AUTH_HEADER = "Authorization"
|
||||||
const val AUTH_PREFIX = "Bearer"
|
const val AUTH_PREFIX = "Bearer"
|
||||||
|
|
||||||
|
private val hasher = MessageDigest.getInstance("SHA-256")
|
||||||
private val cryptograph = AESCryptograph().apply { init(sharedSecret) }
|
private val cryptograph = AESCryptograph().apply { init(sharedSecret) }
|
||||||
|
|
||||||
private data class AuthorizationPayload(
|
private data class AuthorizationPayload(
|
||||||
@@ -26,21 +30,26 @@ object TokenHandler: ApiHandler {
|
|||||||
val userInfos: Json
|
val userInfos: Json
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun getAuthorizationPayload(request: HttpServletRequest): AuthorizationPayload? {
|
private fun parseAuthorizationHeader(request: HttpServletRequest): Pair<String, String>? {
|
||||||
val authorize = request.getHeader(AUTH_HEADER) as String?
|
val authorize = request.getHeader(AUTH_HEADER) as String?
|
||||||
if (authorize != null && authorize.startsWith("$AUTH_PREFIX ")) {
|
if (authorize != null && authorize.startsWith("$AUTH_PREFIX ")) {
|
||||||
val bearer = authorize.substring(AUTH_PREFIX.length + 1)
|
val bearer = authorize.substring(AUTH_PREFIX.length + 1)
|
||||||
val clear = cryptograph.webDecrypt(bearer)
|
val clear = cryptograph.webDecrypt(bearer)
|
||||||
val parts = clear.split(':')
|
val parts = clear.split(':')
|
||||||
if (parts.size == 2) {
|
if (parts.size == 2) {
|
||||||
val sessionId = parts[0]
|
return Pair(parts[0], parts[1])
|
||||||
val accessKey = parts[1]
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAuthorizationPayload(request: HttpServletRequest): AuthorizationPayload? {
|
||||||
|
parseAuthorizationHeader(request)?.let { (sessionId, accessKey) ->
|
||||||
val accessPayload = accesses.getIfPresent(accessKey)
|
val accessPayload = accesses.getIfPresent(accessKey)
|
||||||
if (accessPayload != null && sessionId == accessPayload.getString("session")) {
|
if (accessPayload != null && sessionId == accessPayload.getString("session")) {
|
||||||
return AuthorizationPayload(sessionId, accessKey, accessPayload)
|
return AuthorizationPayload(sessionId, accessKey, accessPayload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,15 +72,15 @@ object TokenHandler: ApiHandler {
|
|||||||
if (challenge != null) {
|
if (challenge != null) {
|
||||||
val email = auth.getString("email")
|
val email = auth.getString("email")
|
||||||
val signature = auth.getString("signature")
|
val signature = auth.getString("signature")
|
||||||
val expectedSignature = cryptograph.webEncrypt(
|
val expectedSignature = hasher.digest(
|
||||||
"${
|
"${
|
||||||
session
|
session
|
||||||
}:${
|
}:${
|
||||||
challenge
|
challenge
|
||||||
}:${
|
}:${
|
||||||
email
|
email
|
||||||
}"
|
}".toByteArray(StandardCharsets.UTF_8)
|
||||||
)
|
).toHex()
|
||||||
if (signature == expectedSignature) {
|
if (signature == expectedSignature) {
|
||||||
val accessKey = Randomizer.randomString(32)
|
val accessKey = Randomizer.randomString(32)
|
||||||
accesses.put(accessKey, Json.Object(
|
accesses.put(accessKey, Json.Object(
|
||||||
@@ -93,10 +102,11 @@ object TokenHandler: ApiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun failed(request: HttpServletRequest, response: HttpServletResponse) {
|
private fun failed(request: HttpServletRequest, response: HttpServletResponse) {
|
||||||
val authPayload = getAuthorizationPayload(request)
|
val authValues = parseAuthorizationHeader(request)
|
||||||
if (authPayload != null && authPayload.sessionId.isNotEmpty()) {
|
if (authValues != null && authValues.first.isNotEmpty()) {
|
||||||
|
val sessionId = authValues.first
|
||||||
val challenge = Randomizer.randomString(32)
|
val challenge = Randomizer.randomString(32)
|
||||||
challenges.put(authPayload.sessionId, challenge)
|
challenges.put(sessionId, challenge)
|
||||||
response.addHeader("WWW-Authenticate", challenge)
|
response.addHeader("WWW-Authenticate", challenge)
|
||||||
response.status = HttpServletResponse.SC_UNAUTHORIZED
|
response.status = HttpServletResponse.SC_UNAUTHORIZED
|
||||||
response.writer.println(Json.Object("status" to "failed", "message" to "unauthorized"))
|
response.writer.println(Json.Object("status" to "failed", "message" to "unauthorized"))
|
||||||
|
@@ -56,6 +56,7 @@ class ApiServlet: HttpServlet() {
|
|||||||
val requestLock = if (request.method == "GET") lock.readLock() else lock.writeLock()
|
val requestLock = if (request.method == "GET") lock.readLock() else lock.writeLock()
|
||||||
try {
|
try {
|
||||||
requestLock.lock()
|
requestLock.lock()
|
||||||
|
logger.logRequest(request, !request.requestURI.contains(".") && request.requestURI.length > 1)
|
||||||
if (checkAuthorization(request, response)) {
|
if (checkAuthorization(request, response)) {
|
||||||
doProtectedRequest(request, response)
|
doProtectedRequest(request, response)
|
||||||
} else {
|
} else {
|
||||||
@@ -68,7 +69,6 @@ class ApiServlet: HttpServlet() {
|
|||||||
|
|
||||||
private fun doProtectedRequest(request: HttpServletRequest, response: HttpServletResponse) {
|
private fun doProtectedRequest(request: HttpServletRequest, response: HttpServletResponse) {
|
||||||
val uri = request.requestURI
|
val uri = request.requestURI
|
||||||
logger.logRequest(request, !uri.contains(".") && uri.length > 1)
|
|
||||||
|
|
||||||
var payload: Json? = null
|
var payload: Json? = null
|
||||||
var reason = "OK"
|
var reason = "OK"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# debug version
|
# debug version
|
||||||
# mvn package && java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5006 -jar application/target/pairgoth-engine.jar
|
mvn -DskipTests package && java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006 -Dpairgoth.mode=client -jar application/target/pairgoth-engine.jar
|
||||||
|
|
||||||
mvn -DskipTests=true package && java -Dpairgoth.mode=client -jar application/target/pairgoth-engine.jar
|
# mvn -DskipTests package && java -Dpairgoth.mode=client -jar application/target/pairgoth-engine.jar
|
||||||
|
@@ -16,3 +16,5 @@ val sharedSecret: String by lazy {
|
|||||||
if (it.length != 16) throw RuntimeException("shared secret must be 16 ascii chars long")
|
if (it.length != 16) throw RuntimeException("shared secret must be 16 ascii chars long")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ByteArray.toHex(): String = joinToString(separator = "") { eachByte -> "%02x".format(eachByte) }
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# debug version
|
# debug version
|
||||||
# mvn package && java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5006 -jar application/target/pairgoth-engine.jar
|
mvn -DskipTests package && java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -Dpairgoth.mode=server -jar application/target/pairgoth-engine.jar
|
||||||
|
|
||||||
mvn -DskipTests=true package && java -Dpairgoth.mode=server -jar application/target/pairgoth-engine.jar
|
# mvn -DskipTests=true package && java -Dpairgoth.mode=server -jar application/target/pairgoth-engine.jar
|
||||||
|
@@ -40,8 +40,9 @@ abstract class OAuthHelper {
|
|||||||
fun getAccessToken(sessionID: String, code: String): String {
|
fun getAccessToken(sessionID: String, code: String): String {
|
||||||
val (url, params) = getAccessTokenURL(code)
|
val (url, params) = getAccessTokenURL(code)
|
||||||
val json = JsonApiClient.post(url, null, *params.toTypedArray()).asObject()
|
val json = JsonApiClient.post(url, null, *params.toTypedArray()).asObject()
|
||||||
val state = json.getString("state") ?: throw IOException("could not get state")
|
// CB TODO - do not check state for now
|
||||||
if (!checkState(state, sessionID)) throw IOException("invalid state")
|
// val state = json.getString("state") ?: throw IOException("could not get state")
|
||||||
|
// if (!checkState(state, sessionID)) throw IOException("invalid state")
|
||||||
return json.getString("access_token") ?: throw IOException("could not get access token")
|
return json.getString("access_token") ?: throw IOException("could not get access token")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ import org.jeudego.pairgoth.web.AuthFilter
|
|||||||
import org.jeudego.pairgoth.web.WebappManager
|
import org.jeudego.pairgoth.web.WebappManager
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
|
||||||
class ApiTool {
|
class ApiTool {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -36,7 +37,22 @@ class ApiTool {
|
|||||||
private fun Json.toRequestBody() = toString().toRequestBody(JSON.toMediaType())
|
private fun Json.toRequestBody() = toString().toRequestBody(JSON.toMediaType())
|
||||||
private fun Request.Builder.process(): Json {
|
private fun Request.Builder.process(): Json {
|
||||||
try {
|
try {
|
||||||
return client.newCall(build()).execute().use { response ->
|
val apiReq = build()
|
||||||
|
if (logger.isTraceEnabled) {
|
||||||
|
logger.trace(">> ${apiReq.method} ${apiReq.url}")
|
||||||
|
apiReq.headers.forEach { header ->
|
||||||
|
logger.trace(" ${header.first} ${header.second}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.trace(" ")
|
||||||
|
return client.newCall(apiReq).execute().use { response ->
|
||||||
|
if (logger.isTraceEnabled) {
|
||||||
|
logger.trace("<< ${response.code} ${response.message}")
|
||||||
|
response.headers.forEach { header ->
|
||||||
|
logger.trace(" ${header.first} ${header.second}")
|
||||||
|
}
|
||||||
|
}
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
when (response.body?.contentType()?.subtype) {
|
when (response.body?.contentType()?.subtype) {
|
||||||
null -> throw Error("null body or content type")
|
null -> throw Error("null body or content type")
|
||||||
@@ -44,6 +60,10 @@ class ApiTool {
|
|||||||
else -> throw Error("unhandled content type: ${response.body!!.contentType()}")
|
else -> throw Error("unhandled content type: ${response.body!!.contentType()}")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (response.code == HttpServletResponse.SC_UNAUTHORIZED) {
|
||||||
|
request.session.removeAttribute(AuthFilter.SESSION_KEY_API_TOKEN)
|
||||||
|
request.session.removeAttribute(AuthFilter.SESSION_KEY_USER)
|
||||||
|
}
|
||||||
when (response.body?.contentType()?.subtype) {
|
when (response.body?.contentType()?.subtype) {
|
||||||
"json" -> Json.parse(response.body!!.string()) ?: throw Error("could not parse error json")
|
"json" -> Json.parse(response.body!!.string()) ?: throw Error("could not parse error json")
|
||||||
else -> throw Error("${response.code} ${response.message}")
|
else -> throw Error("${response.code} ${response.message}")
|
||||||
|
@@ -9,6 +9,7 @@ import org.jeudego.pairgoth.oauth.OauthHelperFactory
|
|||||||
import org.jeudego.pairgoth.util.AESCryptograph
|
import org.jeudego.pairgoth.util.AESCryptograph
|
||||||
import org.jeudego.pairgoth.view.ApiTool
|
import org.jeudego.pairgoth.view.ApiTool
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import java.io.IOException
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import javax.servlet.Filter
|
import javax.servlet.Filter
|
||||||
@@ -95,11 +96,16 @@ class AuthFilter: Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun fetchApiToken(req: HttpServletRequest, user: Json.Object): String? {
|
fun fetchApiToken(req: HttpServletRequest, user: Json.Object): String? {
|
||||||
|
try {
|
||||||
|
logger.trace("getting challenge...")
|
||||||
val challengeReq = Request.Builder().url("${ApiTool.apiRoot}tour/token")
|
val challengeReq = Request.Builder().url("${ApiTool.apiRoot}tour/token")
|
||||||
|
.header("Accept", "application/json")
|
||||||
.header("Authorization", "Bearer ${getBearer(req)}")
|
.header("Authorization", "Bearer ${getBearer(req)}")
|
||||||
.build()
|
.build()
|
||||||
val challengeResp = client.newCall(challengeReq).execute()
|
val challengeResp = client.newCall(challengeReq).execute()
|
||||||
|
challengeResp.use {
|
||||||
if (challengeResp.code == HttpServletResponse.SC_UNAUTHORIZED) {
|
if (challengeResp.code == HttpServletResponse.SC_UNAUTHORIZED) {
|
||||||
|
logger.trace("building answer...")
|
||||||
val email = user.getString("email") ?: "-"
|
val email = user.getString("email") ?: "-"
|
||||||
val challenge = challengeResp.headers["WWW-Authenticate"]
|
val challenge = challengeResp.headers["WWW-Authenticate"]
|
||||||
if (challenge != null) {
|
if (challenge != null) {
|
||||||
@@ -110,25 +116,36 @@ class AuthFilter: Filter {
|
|||||||
challenge
|
challenge
|
||||||
}:${
|
}:${
|
||||||
email
|
email
|
||||||
}".toByteArray(StandardCharsets.UTF_8))
|
}".toByteArray(StandardCharsets.UTF_8)
|
||||||
|
).toHex()
|
||||||
val answer = Json.Object(
|
val answer = Json.Object(
|
||||||
"session" to req.session.id,
|
"session" to req.session.id,
|
||||||
"email" to email,
|
"email" to email,
|
||||||
"signature" to signature
|
"signature" to signature
|
||||||
)
|
)
|
||||||
val answerReq = Request.Builder().url("${ApiTool.apiRoot}tour/token").post(
|
val answerReq = Request.Builder().url("${ApiTool.apiRoot}tour/token")
|
||||||
answer.toString().toRequestBody(ApiTool.JSON.toMediaType())
|
.header("Accept", "application/json")
|
||||||
).build()
|
.post(answer.toString().toRequestBody(ApiTool.JSON.toMediaType()))
|
||||||
|
.build()
|
||||||
val answerResp = client.newCall(answerReq).execute()
|
val answerResp = client.newCall(answerReq).execute()
|
||||||
|
answerResp.use {
|
||||||
if (answerResp.isSuccessful && "json" == answerResp.body?.contentType()?.subtype) {
|
if (answerResp.isSuccessful && "json" == answerResp.body?.contentType()?.subtype) {
|
||||||
val payload = Json.parse(answerResp.body!!.string())
|
val payload = Json.parse(answerResp.body!!.string())
|
||||||
if (payload != null && payload.isObject) {
|
if (payload != null && payload.isObject) {
|
||||||
val token = payload.asObject().getString("token")
|
val token = payload.asObject().getString("token")
|
||||||
if (token != null) return token
|
if (token != null) {
|
||||||
|
logger.trace("got token $token")
|
||||||
|
return token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
logger.warn("could not fetch access token", e)
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
level = info
|
|
@@ -59,17 +59,44 @@ private fun cleanup() {
|
|||||||
FileUtils.deleteDirectory(webapps.toFile())
|
FileUtils.deleteDirectory(webapps.toFile())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val allowedModes = setOf("standalone", "server", "client")
|
||||||
|
|
||||||
private fun readProperties() {
|
private fun readProperties() {
|
||||||
val defaultProps = getResource("/server.default.properties") ?: throw Error("missing default server properties")
|
// do a first pass at determining the final 'mode', since it will influence other default value
|
||||||
|
var mode = "standalone"
|
||||||
|
val userProperties = File("./pairgoth.properties")
|
||||||
|
if (userProperties.exists()) {
|
||||||
|
val userProps = Properties()
|
||||||
|
userProps.load(FileReader(userProperties))
|
||||||
|
if (userProps.contains("mode")) mode = userProps.getProperty("mode")
|
||||||
|
}
|
||||||
|
val systemMode: String? = System.getProperty("pairgoth.mode")
|
||||||
|
if (systemMode != null) {
|
||||||
|
mode = systemMode
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allowedModes.contains(mode)) throw Error("invalid mode: $mode")
|
||||||
|
|
||||||
|
// read default properties
|
||||||
|
val defaultProps = getResource("/${mode}.default.properties") ?: throw Error("missing default server properties")
|
||||||
defaultProps.openStream().use {
|
defaultProps.openStream().use {
|
||||||
serverProps.load(InputStreamReader(it, StandardCharsets.UTF_8))
|
serverProps.load(InputStreamReader(it, StandardCharsets.UTF_8))
|
||||||
}
|
}
|
||||||
val properties = File("./pairgoth.properties")
|
// default env depends upon the presence of the pom.xml file
|
||||||
if (properties.exists()) {
|
|
||||||
serverProps.load(FileReader(properties))
|
|
||||||
}
|
|
||||||
val env = if (File("./pom.xml").exists()) "dev" else "prod"
|
val env = if (File("./pom.xml").exists()) "dev" else "prod"
|
||||||
serverProps["env"] = env
|
serverProps["env"] = env
|
||||||
|
// read user properties
|
||||||
|
if (userProperties.exists()) {
|
||||||
|
serverProps.load(FileReader(userProperties))
|
||||||
|
}
|
||||||
|
// read system properties
|
||||||
|
System.getProperties().forEach {
|
||||||
|
val key = it.key as String
|
||||||
|
val value = it.value as String
|
||||||
|
if (key.startsWith("pairgoth.")) {
|
||||||
|
serverProps[key.removePrefix("pairgoth.")] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun publishProperties() {
|
private fun publishProperties() {
|
||||||
@@ -149,12 +176,23 @@ private fun launchServer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val webappUrl = URL(
|
val webappUrl = when (mode) {
|
||||||
serverProps.getProperty("webapp.protocol") ?: throw Error("missing property webapp.protocol"),
|
"client", "standalone" ->
|
||||||
|
URL(
|
||||||
serverProps.getProperty("webapp.protocol") ?: throw Error("missing property webapp.protocol"),
|
serverProps.getProperty("webapp.protocol") ?: throw Error("missing property webapp.protocol"),
|
||||||
|
serverProps.getProperty("webapp.host") ?: throw Error("missing property webapp.host"),
|
||||||
serverProps.getProperty("webapp.port")?.toInt() ?: 80,
|
serverProps.getProperty("webapp.port")?.toInt() ?: 80,
|
||||||
"/"
|
"/"
|
||||||
)
|
)
|
||||||
|
"server" ->
|
||||||
|
URL(
|
||||||
|
serverProps.getProperty("api.protocol") ?: throw Error("missing property api.protocol"),
|
||||||
|
serverProps.getProperty("api.host") ?: throw Error("missing property api.host"),
|
||||||
|
serverProps.getProperty("api.port")?.toInt() ?: 80,
|
||||||
|
"/"
|
||||||
|
)
|
||||||
|
else -> throw Error("invalid mode: $mode")
|
||||||
|
}
|
||||||
val secure = webappUrl.protocol == "https"
|
val secure = webappUrl.protocol == "https"
|
||||||
|
|
||||||
// create server
|
// create server
|
||||||
|
18
webserver/src/main/resources/client.default.properties
Normal file
18
webserver/src/main/resources/client.default.properties
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
mode = standalone
|
||||||
|
# webapp connector
|
||||||
|
webapp.protocol = http
|
||||||
|
webapp.host = localhost
|
||||||
|
webapp.port = 8080
|
||||||
|
webapp.context = /
|
||||||
|
webapp.external.url = http://localhost:8080
|
||||||
|
|
||||||
|
# api connector
|
||||||
|
api.protocol = http
|
||||||
|
api.host = localhost
|
||||||
|
api.port = 8085
|
||||||
|
api.context = /api/tour
|
||||||
|
api.external.url = http://localhost:8085/api/
|
||||||
|
|
||||||
|
webapp.ssl.key = jar:file:$jar!/ssl/localhost.key
|
||||||
|
webapp.ssl.pass =
|
||||||
|
webapp.ssl.cert = jar:file:$jar!/ssl/localhost.crt
|
@@ -1,17 +1,17 @@
|
|||||||
mode = standalone
|
mode = server
|
||||||
# webapp connector
|
# webapp connector
|
||||||
webapp.protocol = http
|
webapp.protocol = http
|
||||||
webapp.interface = localhost
|
webapp.host = localhost
|
||||||
webapp.port = 8080
|
webapp.port = 8080
|
||||||
webapp.context = /
|
webapp.context = /
|
||||||
webapp.external.url = http://localhost:8080
|
webapp.external.url = http://localhost:8080
|
||||||
|
|
||||||
# api connector
|
# api connector
|
||||||
api.protocol = http
|
api.protocol = http
|
||||||
api.interface = localhost
|
api.host = localhost
|
||||||
api.port = 8080
|
api.port = 8085
|
||||||
api.context = /api/tour
|
api.context = /api/tour
|
||||||
api.external.url = http://localhost:8080/api/
|
api.external.url = http://localhost:8085/api/
|
||||||
|
|
||||||
webapp.ssl.key = jar:file:$jar!/ssl/localhost.key
|
webapp.ssl.key = jar:file:$jar!/ssl/localhost.key
|
||||||
webapp.ssl.pass =
|
webapp.ssl.pass =
|
||||||
|
18
webserver/src/main/resources/standalone.default.properties
Normal file
18
webserver/src/main/resources/standalone.default.properties
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
mode = standalone
|
||||||
|
# webapp connector
|
||||||
|
webapp.protocol = http
|
||||||
|
webapp.host = localhost
|
||||||
|
webapp.port = 8080
|
||||||
|
webapp.context = /
|
||||||
|
webapp.external.url = http://localhost:8080
|
||||||
|
|
||||||
|
# api connector
|
||||||
|
api.protocol = http
|
||||||
|
api.host = localhost
|
||||||
|
api.port = 8080
|
||||||
|
api.context = /api/tour
|
||||||
|
api.external.url = http://localhost:8080/api/
|
||||||
|
|
||||||
|
webapp.ssl.key = jar:file:$jar!/ssl/localhost.key
|
||||||
|
webapp.ssl.pass =
|
||||||
|
webapp.ssl.cert = jar:file:$jar!/ssl/localhost.crt
|
Reference in New Issue
Block a user