feat: 認証の確認の実装を追加

This commit is contained in:
usbharu 2023-05-01 09:12:15 +09:00
parent f153ca85f3
commit bf6fe19ede
6 changed files with 84 additions and 15 deletions

View File

@ -1,21 +1,20 @@
package dev.usbharu.hideout.plugins package dev.usbharu.hideout.plugins
import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.plugins.defaultheaders.* import io.ktor.server.plugins.defaultheaders.*
import io.ktor.server.plugins.forwardedheaders.* import io.ktor.server.plugins.forwardedheaders.*
fun Application.configureHTTP() { fun Application.configureHTTP() {
install(CORS) { // install(CORS) {
allowMethod(HttpMethod.Options) // allowMethod(HttpMethod.Options)
allowMethod(HttpMethod.Put) // allowMethod(HttpMethod.Put)
allowMethod(HttpMethod.Delete) // allowMethod(HttpMethod.Delete)
allowMethod(HttpMethod.Patch) // allowMethod(HttpMethod.Patch)
allowHeader(HttpHeaders.Authorization) // allowHeader(HttpHeaders.Authorization)
allowHeader("MyCustomHeader") // allow
anyHost() // @TODO: Don't do this in production if possible. Try to limit it. // allowHeader("MyCustomHeader")
} // anyHost() // @TODO: Don't do this in production if possible. Try to limit it.
// }
install(DefaultHeaders) { install(DefaultHeaders) {
header("X-Engine", "Ktor") // will send this header with each response header("X-Engine", "Ktor") // will send this header with each response
} }

View File

@ -4,6 +4,7 @@ import dev.usbharu.hideout.routing.activitypub.inbox
import dev.usbharu.hideout.routing.activitypub.outbox import dev.usbharu.hideout.routing.activitypub.outbox
import dev.usbharu.hideout.routing.activitypub.usersAP import dev.usbharu.hideout.routing.activitypub.usersAP
import dev.usbharu.hideout.routing.api.v1.statuses import dev.usbharu.hideout.routing.api.v1.statuses
import dev.usbharu.hideout.routing.authTestRouting
import dev.usbharu.hideout.routing.wellknown.webfinger import dev.usbharu.hideout.routing.wellknown.webfinger
import dev.usbharu.hideout.service.IPostService import dev.usbharu.hideout.service.IPostService
import dev.usbharu.hideout.service.activitypub.ActivityPubService import dev.usbharu.hideout.service.activitypub.ActivityPubService
@ -31,5 +32,7 @@ fun Application.configureRouting(
route("/api/v1") { route("/api/v1") {
statuses(postService) statuses(postService)
} }
authTestRouting()
} }
} }

View File

@ -51,6 +51,7 @@ fun Application.configureSecurity(userAuthService: IUserAuthService, metaReposit
realm = myRealm realm = myRealm
verifier(jwkProvider, issuer) { verifier(jwkProvider, issuer) {
acceptLeeway(3) acceptLeeway(3)
} }
validate { jwtCredential -> validate { jwtCredential ->
if (jwtCredential.payload.getClaim("username").asString().isNotEmpty()) { if (jwtCredential.payload.getClaim("username").asString().isNotEmpty()) {
@ -59,6 +60,9 @@ fun Application.configureSecurity(userAuthService: IUserAuthService, metaReposit
null null
} }
} }
challenge { defaultScheme, realm ->
call.respondRedirect("/login")
}
} }
} }
@ -78,7 +82,7 @@ fun Application.configureSecurity(userAuthService: IUserAuthService, metaReposit
.withClaim("username", user.username) .withClaim("username", user.username)
.withExpiresAt(Date(System.currentTimeMillis() + 60000)) .withExpiresAt(Date(System.currentTimeMillis() + 60000))
.sign(Algorithm.RSA256(publicKey, privateKey as RSAPrivateKey)) .sign(Algorithm.RSA256(publicKey, privateKey as RSAPrivateKey))
return@post call.respond(hashSetOf("token" to token)) return@post call.respond(token)
} }
get("/.well-known/jwks.json") { get("/.well-known/jwks.json") {

View File

@ -0,0 +1,19 @@
package dev.usbharu.hideout.routing
import dev.usbharu.hideout.plugins.TOKEN_AUTH
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Routing.authTestRouting(){
authenticate(TOKEN_AUTH){
get("/auth-check"){
val principal = call.principal<JWTPrincipal>()
val username = principal!!.payload.getClaim("username")
call.respondText("Hello $username")
}
}
}

View File

@ -1,5 +1,47 @@
import {Component} from "solid-js"; import {Component, createSignal} from "solid-js";
export const App: Component = () => { export const App: Component = () => {
return (<p>aaa</p>)
const fn = (form: HTMLButtonElement) => {
console.log(form)
}
const [username, setUsername] = createSignal("")
const [password, setPassword] = createSignal("")
return (
<form onSubmit={function (e: SubmitEvent) {
e.preventDefault()
fetch("/login", {
method: "POST",
body: JSON.stringify({username: username(), password: password()}),
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.text())
.then(res => fetch("/auth-check", {
method: "GET",
headers: {
'Authorization': 'Bearer ' + res
}
})).then(res => console.log(res))
}
}>
<input name="username" type="text" placeholder="Username" required
onChange={(e) => setUsername(e.currentTarget.value)}/>
<input name="password" type="password" placeholder="Password" required
onChange={(e) => setPassword(e.currentTarget.value)}/>
<button type="submit">Submit</button>
</form>
)
}
declare module 'solid-js' {
namespace JSX {
interface Directives {
fn: (form: HTMLFormElement) => void
}
}
} }

View File

@ -7,7 +7,9 @@ export default defineConfig({
server: { server: {
port: 3000, port: 3000,
proxy: { proxy: {
'/api': 'http://localhost:8080' '/api': 'http://localhost:8080',
'/login': 'http://localhost:8080',
'/auth-check': 'http://localhost:8080',
} }
}, },
root: './src/main/web', root: './src/main/web',