Oauth2Properties.kt
package io.github.lishangbu.avalon.oauth2.common.properties
import org.springframework.boot.autoconfigure.AutoConfiguration
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.convert.DurationStyle
import java.time.Duration
import java.time.temporal.ChronoUnit
/**
* OAuth2 配置属性
*
* 定义认证参数名、验证码策略、登录失败限制和 JWT 密钥位置等配置
*/
@AutoConfiguration
@ConfigurationProperties(prefix = "oauth2")
class Oauth2Properties {
/** 忽略认证的 URL 列表 */
var ignoreUrls: MutableList<String> = mutableListOf()
/** 用户名参数名 */
var usernameParameterName: String = "username"
/** 密码参数名 */
var passwordParameterName: String = "password"
/** 手机号参数名 */
var phoneParameterName: String = "phone"
/** 短信验证码参数名 */
var smsCodeParameterName: String = "sms_code"
/** 邮箱参数名 */
var emailParameterName: String = "email"
/** 邮箱验证码参数名 */
var emailCodeParameterName: String = "email_code"
/** 短信验证码长度 */
var smsCodeLength: Int? = 6
/** 短信验证码有效期 */
private var smsCodeTimeToLive: String? = "5m"
/** 短信验证码重发间隔 */
private var smsCodeResendInterval: String? = "60s"
/** 邮箱验证码长度 */
var emailCodeLength: Int? = 6
/** 邮箱验证码有效期 */
private var emailCodeTimeToLive: String? = "5m"
/** 邮箱验证码重发间隔 */
private var emailCodeResendInterval: String? = "60s"
/** 最大登录失败次数 */
var maxLoginFailures: Int? = 5
/** 登录锁定时长 */
private var loginLockDuration: String? = "15m"
/** 登录失败跟踪存储类型 */
var loginFailureTrackerStoreType: LoginFailureTrackerStoreType = LoginFailureTrackerStoreType.MEMORY
/** 登录失败跟踪 Redis Key 前缀 */
var loginFailureTrackerKeyPrefix: String = "oauth2:login-failure"
/** 登录失败跟踪 JDBC 表名 */
var loginFailureTrackerJdbcTableName: String = "oauth2_login_failure"
/** 签发者 URL */
var issuerUrl: String? = null
/** JWT 公钥文件位置 */
var jwtPublicKeyLocation: String? = null
/** JWT 私钥文件位置 */
var jwtPrivateKeyLocation: String? = null
/** 获取登录锁定时长 */
fun getLoginLockDuration(): Duration? {
val value = loginLockDuration
if (value.isNullOrBlank()) {
return null
}
return try {
DurationStyle.detectAndParse(value.trim(), ChronoUnit.MINUTES)
} catch (_: IllegalArgumentException) {
null
}
}
/** 设置登录锁定时长 */
fun setLoginLockDuration(loginLockDuration: String?) {
this.loginLockDuration = loginLockDuration
}
/** 获取短信验证码有效期 */
fun getSmsCodeTimeToLiveDuration(): Duration = parseDuration(smsCodeTimeToLive, Duration.ofMinutes(5), ChronoUnit.MINUTES)
/** 获取短信验证码重发间隔 */
fun getSmsCodeResendIntervalDuration(): Duration = parseDuration(smsCodeResendInterval, Duration.ofSeconds(60), ChronoUnit.SECONDS)
/** 获取邮箱验证码有效期 */
fun getEmailCodeTimeToLiveDuration(): Duration = parseDuration(emailCodeTimeToLive, Duration.ofMinutes(5), ChronoUnit.MINUTES)
/** 获取邮箱验证码重发间隔 */
fun getEmailCodeResendIntervalDuration(): Duration = parseDuration(emailCodeResendInterval, Duration.ofSeconds(60), ChronoUnit.SECONDS)
/** 解析时长配置 */
private fun parseDuration(
value: String?,
fallback: Duration,
defaultUnit: ChronoUnit,
): Duration {
if (value.isNullOrBlank()) {
return fallback
}
return try {
DurationStyle.detectAndParse(value.trim(), defaultUnit)
} catch (_: IllegalArgumentException) {
fallback
}
}
companion object {
/** 配置前缀 */
const val PREFIX = "oauth2"
}
}