mirror of https://github.com/usbharu/Hideout.git
test: テストを修正
This commit is contained in:
parent
cc046393d6
commit
b1356e8496
|
@ -56,6 +56,7 @@ class InboxTest {
|
|||
.post("/inbox") {
|
||||
content = "{}"
|
||||
contentType = MediaType.APPLICATION_JSON
|
||||
header("Signature", "")
|
||||
}
|
||||
.asyncDispatch()
|
||||
.andExpect { status { isAccepted() } }
|
||||
|
@ -80,6 +81,7 @@ class InboxTest {
|
|||
.post("/users/hoge/inbox") {
|
||||
content = "{}"
|
||||
contentType = MediaType.APPLICATION_JSON
|
||||
header("Signature", "")
|
||||
}
|
||||
.asyncDispatch()
|
||||
.andExpect { status { isAccepted() } }
|
||||
|
|
|
@ -42,7 +42,6 @@ class InboxControllerImpl(private val apService: APService) : InboxController {
|
|||
try {
|
||||
val url = request.requestURL.toString()
|
||||
|
||||
|
||||
val headers =
|
||||
headersList.associateWith { header -> request.getHeaders(header)?.toList().orEmpty() }
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import dev.usbharu.hideout.core.query.UserQueryService
|
|||
import dev.usbharu.hideout.core.service.job.JobProcessor
|
||||
import dev.usbharu.hideout.util.RsaUtil
|
||||
import dev.usbharu.httpsignature.common.HttpHeaders
|
||||
import dev.usbharu.httpsignature.common.HttpMethod
|
||||
import dev.usbharu.httpsignature.common.HttpRequest
|
||||
import dev.usbharu.httpsignature.common.PublicKey
|
||||
import dev.usbharu.httpsignature.verify.HttpSignatureVerifier
|
||||
|
@ -34,6 +35,14 @@ class InboxJobProcessor(
|
|||
) : JobProcessor<InboxJobParam, InboxJob> {
|
||||
|
||||
private suspend fun verifyHttpSignature(httpRequest: HttpRequest, signature: Signature): Boolean {
|
||||
val requiredHeaders = when (httpRequest.method) {
|
||||
HttpMethod.GET -> getRequiredHeaders
|
||||
HttpMethod.POST -> postRequiredHeaders
|
||||
}
|
||||
if (signature.headers.containsAll(requiredHeaders).not()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val user = try {
|
||||
userQueryService.findByKeyId(signature.keyId)
|
||||
} catch (_: FailedToGetResourcesException) {
|
||||
|
@ -96,5 +105,7 @@ class InboxJobProcessor(
|
|||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(InboxJobProcessor::class.java)
|
||||
private val postRequiredHeaders = listOf("(request-target)", "date", "host", "digest")
|
||||
private val getRequiredHeaders = listOf("(request-target)", "date", "host")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ class SecurityConfig {
|
|||
userQueryService: UserQueryService
|
||||
): HttpSignatureFilter {
|
||||
val httpSignatureFilter =
|
||||
HttpSignatureFilter(DefaultSignatureHeaderParser(), transaction, apUserService, userQueryService)
|
||||
HttpSignatureFilter(DefaultSignatureHeaderParser())
|
||||
httpSignatureFilter.setAuthenticationManager(authenticationManager)
|
||||
httpSignatureFilter.setContinueFilterChainOnUnsuccessfulAuthentication(false)
|
||||
val authenticationEntryPointFailureHandler =
|
||||
|
@ -134,18 +134,20 @@ class SecurityConfig {
|
|||
@Bean
|
||||
fun httpSignatureAuthenticationProvider(transaction: Transaction): PreAuthenticatedAuthenticationProvider {
|
||||
val provider = PreAuthenticatedAuthenticationProvider()
|
||||
val signatureHeaderParser = DefaultSignatureHeaderParser()
|
||||
provider.setPreAuthenticatedUserDetailsService(
|
||||
HttpSignatureUserDetailsService(
|
||||
userQueryService,
|
||||
HttpSignatureVerifierComposite(
|
||||
mapOf(
|
||||
"rsa-sha256" to RsaSha256HttpSignatureVerifier(
|
||||
DefaultSignatureHeaderParser(), RsaSha256HttpSignatureSigner()
|
||||
signatureHeaderParser, RsaSha256HttpSignatureSigner()
|
||||
)
|
||||
),
|
||||
DefaultSignatureHeaderParser()
|
||||
signatureHeaderParser
|
||||
),
|
||||
transaction
|
||||
transaction,
|
||||
signatureHeaderParser
|
||||
)
|
||||
)
|
||||
provider.setUserDetailsChecker(AccountStatusUserDetailsChecker())
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.springframework.httpsignature
|
||||
|
||||
import dev.usbharu.hideout.activitypub.service.objects.user.APUserService
|
||||
import dev.usbharu.hideout.application.external.Transaction
|
||||
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
|
||||
import dev.usbharu.hideout.core.query.UserQueryService
|
||||
import dev.usbharu.httpsignature.common.HttpHeaders
|
||||
import dev.usbharu.httpsignature.common.HttpMethod
|
||||
import dev.usbharu.httpsignature.common.HttpRequest
|
||||
import dev.usbharu.httpsignature.verify.SignatureHeaderParser
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter
|
||||
import java.net.URL
|
||||
|
||||
class HttpSignatureFilter(
|
||||
private val httpSignatureHeaderParser: SignatureHeaderParser,
|
||||
private val transaction: Transaction,
|
||||
private val apUserService: APUserService,
|
||||
private val userQueryService: UserQueryService
|
||||
private val httpSignatureHeaderParser: SignatureHeaderParser
|
||||
) :
|
||||
AbstractPreAuthenticatedProcessingFilter() {
|
||||
override fun getPreAuthenticatedPrincipal(request: HttpServletRequest?): Any? {
|
||||
|
@ -33,15 +25,6 @@ class HttpSignatureFilter(
|
|||
} catch (_: RuntimeException) {
|
||||
return ""
|
||||
}
|
||||
runBlocking {
|
||||
transaction.transaction {
|
||||
try {
|
||||
userQueryService.findByKeyId(signature.keyId)
|
||||
} catch (_: FailedToGetResourcesException) {
|
||||
apUserService.fetchPerson(signature.keyId)
|
||||
}
|
||||
}
|
||||
}
|
||||
return signature.keyId
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,12 @@ import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
|
|||
import dev.usbharu.hideout.core.domain.exception.HttpSignatureVerifyException
|
||||
import dev.usbharu.hideout.core.query.UserQueryService
|
||||
import dev.usbharu.hideout.util.RsaUtil
|
||||
import dev.usbharu.httpsignature.common.HttpMethod
|
||||
import dev.usbharu.httpsignature.common.HttpRequest
|
||||
import dev.usbharu.httpsignature.common.PublicKey
|
||||
import dev.usbharu.httpsignature.verify.FailedVerification
|
||||
import dev.usbharu.httpsignature.verify.HttpSignatureVerifier
|
||||
import dev.usbharu.httpsignature.verify.SignatureHeaderParser
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.security.authentication.BadCredentialsException
|
||||
|
@ -20,14 +22,16 @@ import org.springframework.security.web.authentication.preauth.PreAuthenticatedA
|
|||
class HttpSignatureUserDetailsService(
|
||||
private val userQueryService: UserQueryService,
|
||||
private val httpSignatureVerifier: HttpSignatureVerifier,
|
||||
private val transaction: Transaction
|
||||
private val transaction: Transaction,
|
||||
private val httpSignatureHeaderParser: SignatureHeaderParser
|
||||
) :
|
||||
AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
|
||||
override fun loadUserDetails(token: PreAuthenticatedAuthenticationToken): UserDetails = runBlocking {
|
||||
if (token.principal !is String) {
|
||||
throw IllegalStateException("Token is not String")
|
||||
}
|
||||
if (token.credentials !is HttpRequest) {
|
||||
val credentials = token.credentials
|
||||
if (credentials !is HttpRequest) {
|
||||
throw IllegalStateException("Credentials is not HttpRequest")
|
||||
}
|
||||
|
||||
|
@ -40,10 +44,25 @@ class HttpSignatureUserDetailsService(
|
|||
}
|
||||
}
|
||||
|
||||
val signature = httpSignatureHeaderParser.parse(credentials.headers)
|
||||
|
||||
val requiredHeaders = when (credentials.method) {
|
||||
HttpMethod.GET -> getRequiredHeaders
|
||||
HttpMethod.POST -> postRequiredHeaders
|
||||
}
|
||||
if (signature.headers.containsAll(requiredHeaders).not()) {
|
||||
logger.warn(
|
||||
"FAILED Verify HTTP Signature. required headers: {} but actual: {}",
|
||||
requiredHeaders,
|
||||
signature.headers
|
||||
)
|
||||
throw BadCredentialsException("HTTP Signature. required headers: $requiredHeaders")
|
||||
}
|
||||
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
val verify = try {
|
||||
httpSignatureVerifier.verify(
|
||||
token.credentials as HttpRequest,
|
||||
credentials,
|
||||
PublicKey(RsaUtil.decodeRsaPublicKeyPem(findByKeyId.publicKey), keyId)
|
||||
)
|
||||
} catch (e: RuntimeException) {
|
||||
|
@ -67,5 +86,7 @@ class HttpSignatureUserDetailsService(
|
|||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(HttpSignatureUserDetailsService::class.java)
|
||||
private val postRequiredHeaders = listOf("(request-target)", "date", "host", "digest")
|
||||
private val getRequiredHeaders = listOf("(request-target)", "date", "host")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ class InboxControllerImplTest {
|
|||
.post("/inbox") {
|
||||
content = json
|
||||
contentType = MediaType.APPLICATION_JSON
|
||||
header("Signature", "")
|
||||
}
|
||||
.asyncDispatch()
|
||||
.andExpect {
|
||||
|
@ -71,6 +72,7 @@ class InboxControllerImplTest {
|
|||
.post("/inbox") {
|
||||
content = json
|
||||
contentType = MediaType.APPLICATION_JSON
|
||||
header("Signature", "")
|
||||
}
|
||||
.asyncDispatch()
|
||||
.andExpect {
|
||||
|
@ -96,6 +98,7 @@ class InboxControllerImplTest {
|
|||
.post("/inbox") {
|
||||
content = json
|
||||
contentType = MediaType.APPLICATION_JSON
|
||||
header("Signature", "")
|
||||
}
|
||||
.asyncDispatch()
|
||||
.andExpect {
|
||||
|
@ -123,6 +126,7 @@ class InboxControllerImplTest {
|
|||
.post("/users/hoge/inbox") {
|
||||
content = json
|
||||
contentType = MediaType.APPLICATION_JSON
|
||||
header("Signature", "")
|
||||
}
|
||||
.asyncDispatch()
|
||||
.andExpect {
|
||||
|
@ -140,6 +144,7 @@ class InboxControllerImplTest {
|
|||
.post("/users/hoge/inbox") {
|
||||
content = json
|
||||
contentType = MediaType.APPLICATION_JSON
|
||||
header("Signature", "")
|
||||
}
|
||||
.asyncDispatch()
|
||||
.andExpect {
|
||||
|
@ -165,6 +170,7 @@ class InboxControllerImplTest {
|
|||
.post("/users/hoge/inbox") {
|
||||
content = json
|
||||
contentType = MediaType.APPLICATION_JSON
|
||||
header("Signature", "")
|
||||
}
|
||||
.asyncDispatch()
|
||||
.andExpect {
|
||||
|
|
Loading…
Reference in New Issue