Skip to content

Commit

Permalink
feat: allow basic auth
Browse files Browse the repository at this point in the history
  • Loading branch information
sgpublic committed Jun 1, 2024
1 parent 089fae2 commit dd64170
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@
| AGENT_GATE_TARGET_NAME | --base-target-name | 被 AgentGate 保护的目标服务的名称。 | (启动时尝试从 `$AGENT_GATE_TARGET_URL$AGENT_GATE_TARGET_HOME_PATH` 所指向的 HTML 中获取,获取失败则为 `AgentGate`|
| AGENT_GATE_AUTH_USERNAME | --auth-username | 认证用户名。 | |
| AGENT_GATE_AUTH_PASSWORD | --auth-password | 认证密码。 | |
| AGENT_GATE_AUTH_ALLOW_BASIC | --auth-allow-basic | 允许使用 basic 认证方式以适配第三方工具。 | false |
| AGENT_GATE_TOKEN_SECURITY_KEY | --token-secret-key | token 的签名密钥。 | (每次启动随机生成 UUID) |
| AGENT_GATE_TOKEN_EXPIRE | --token-expire | 认证有效期,小于 0 则代表仅当前会话有效。 | 3600 * 24(即一天) |
| AGENT_GATE_TOKEN_COOKIE_KEY | --token-cookie-key | 自定义 cookie 的 key,以避免与原有服务冲突。 | X-AgentGate-Auth |

配置文件仅支持 yaml 格式,配置项优先使用排序:环境变量 > 命令行参数 > 配置文件
配置项优先使用排序:环境变量 > 命令行参数。

## 部署

Expand Down Expand Up @@ -60,5 +61,6 @@ services:
- [x] 初步完成认证拦截页面
- [x] 支持环境变量配置参数
- [x] 支持命令行传递参数
- [x] 支持 basic 认证方式
- [ ] 支持自定义前端页面
- [ ] 支持内网跳过认证
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ object Config: CliktCommand(
val AGENT_GATE_AUTH_PASSWORD: String by option("--auth-password", envvar = "AGENT_GATE_AUTH_PASSWORD")
.required()
.help("auth password")
val AGENT_GATE_AUTH_ALLOW_BASIC: Boolean by option("--auth-allow-basic", envvar = "AGENT_GATE_AUTH_ALLOW_BASIC")
.flag()
.help("allow basic auth")

val AGENT_GATE_TOKEN_SECURITY_KEY: String by option("--token-security-key", envvar = "AGENT_GATE_TOKEN_SECURITY_KEY")
.default(UUID.randomUUID().toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import io.github.sgpublic.agentgate.Config
import io.github.sgpublic.agentgate.controller.ApiController
import io.github.sgpublic.agentgate.exception.FailedResult
import io.github.sgpublic.agentgate.exception.write
import io.github.sgpublic.agentgate.service.AuthService.checkBasicAuth
import io.github.sgpublic.agentgate.service.AuthService.checkTag
import io.github.sgpublic.kotlin.util.log
import org.springframework.cloud.gateway.filter.GatewayFilter
import org.springframework.cloud.gateway.filter.GatewayFilterChain
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.http.server.reactive.ServerHttpRequest
import org.springframework.web.server.ServerWebExchange
Expand Down Expand Up @@ -46,11 +48,15 @@ object TokenFilterImpl: GatewayFilter {
}

val auth = request.cookies[Config.AGENT_GATE_TOKEN_COOKIE_KEY]
?.firstOrNull()?.value
val errorType = if (auth != null) {
checkTag(auth)
} else {
FailedResult.Auth.ExpiredToken
?.firstOrNull()?.value?.takeIf { it.isNotBlank() }
?: request.headers[HttpHeaders.AUTHORIZATION]?.firstOrNull()
val errorType = when {
Config.AGENT_GATE_AUTH_ALLOW_BASIC && auth?.startsWith("Basic ") == true ->
checkBasicAuth(auth)
auth != null ->
checkTag(auth)
else ->
FailedResult.Auth.ExpiredToken
}
if (errorType == null) {
return chain.filter(exchange)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ package io.github.sgpublic.agentgate.service

import io.github.sgpublic.agentgate.Config
import io.github.sgpublic.agentgate.exception.FailedResult
import io.github.sgpublic.kotlin.core.util.BASE_64
import io.github.sgpublic.kotlin.core.util.MD5_FULL_COMPRESSED
import io.github.sgpublic.kotlin.core.util.ORIGIN_BASE64
import io.github.sgpublic.kotlin.util.log
import io.jsonwebtoken.Claims
import io.jsonwebtoken.JwtException
import io.jsonwebtoken.JwtParser
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.security.Keys
import kotlinx.serialization.Serializable
import org.jsoup.Connection.Base
import java.nio.charset.StandardCharsets
import java.util.*
import javax.crypto.SecretKey

Expand All @@ -33,6 +37,15 @@ object AuthService {
return@lazy Jwts.parser().verifyWith(secretKey).build()
}

fun checkBasicAuth(basic: String): FailedResult? {
val (username, password) = basic.substring(6)
.ORIGIN_BASE64.toString(StandardCharsets.UTF_8)
.split(":")
return FailedResult.Auth.WrongPassword.takeUnless {
username == Config.AGENT_GATE_AUTH_USERNAME && password == Config.AGENT_GATE_AUTH_PASSWORD
}
}

fun checkTag(token: String): FailedResult? {
try {
val claims: Claims = parser.parseSignedClaims(token).payload
Expand Down

0 comments on commit dd64170

Please sign in to comment.