mirror of https://github.com/usbharu/Hideout.git
feat: WebFingerのエンドポイントを追加
This commit is contained in:
parent
b36e79048a
commit
63cb3427e4
|
@ -12,10 +12,10 @@ import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.core.annotation.Order
|
import org.springframework.core.annotation.Order
|
||||||
import org.springframework.http.MediaType
|
|
||||||
import org.springframework.security.config.Customizer
|
import org.springframework.security.config.Customizer
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
|
@ -28,7 +28,6 @@ import org.springframework.security.oauth2.server.authorization.token.OAuth2Toke
|
||||||
import org.springframework.security.web.SecurityFilterChain
|
import org.springframework.security.web.SecurityFilterChain
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint
|
||||||
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher
|
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher
|
||||||
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher
|
|
||||||
import org.springframework.web.servlet.handler.HandlerMappingIntrospector
|
import org.springframework.web.servlet.handler.HandlerMappingIntrospector
|
||||||
import java.security.KeyPairGenerator
|
import java.security.KeyPairGenerator
|
||||||
import java.security.interfaces.RSAPrivateKey
|
import java.security.interfaces.RSAPrivateKey
|
||||||
|
@ -36,6 +35,7 @@ import java.security.interfaces.RSAPublicKey
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@EnableWebSecurity(debug = true)
|
@EnableWebSecurity(debug = true)
|
||||||
|
@EnableWebFluxSecurity()
|
||||||
@Configuration
|
@Configuration
|
||||||
class SecurityConfig {
|
class SecurityConfig {
|
||||||
|
|
||||||
|
@ -47,9 +47,8 @@ class SecurityConfig {
|
||||||
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http)
|
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http)
|
||||||
http
|
http
|
||||||
.exceptionHandling {
|
.exceptionHandling {
|
||||||
it.defaultAuthenticationEntryPointFor(
|
it.authenticationEntryPoint(
|
||||||
LoginUrlAuthenticationEntryPoint("/login"),
|
LoginUrlAuthenticationEntryPoint("/login")
|
||||||
MediaTypeRequestMatcher(MediaType.TEXT_HTML)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.oauth2ResourceServer {
|
.oauth2ResourceServer {
|
||||||
|
@ -58,29 +57,23 @@ class SecurityConfig {
|
||||||
return http.build()
|
return http.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Order(2)
|
@Order(2)
|
||||||
fun defaultSecurityFilterChain(http: HttpSecurity, introspector: HandlerMappingIntrospector): SecurityFilterChain {
|
fun defaultSecurityFilterChain(http: HttpSecurity, introspector: HandlerMappingIntrospector): SecurityFilterChain {
|
||||||
val builder = MvcRequestMatcher.Builder(introspector)
|
val builder = MvcRequestMatcher.Builder(introspector)
|
||||||
|
|
||||||
http.authorizeHttpRequests {
|
|
||||||
it.requestMatchers(builder.pattern("/api/v1/**")).hasAnyAuthority("SCOPE_read", "SCOPE_read:accounts")
|
|
||||||
}
|
|
||||||
http
|
|
||||||
.authorizeHttpRequests {
|
|
||||||
it.requestMatchers(
|
|
||||||
builder.pattern("/inbox"),
|
|
||||||
builder.pattern("/api/v1/apps"),
|
|
||||||
builder.pattern("/api/v1/instance/**")
|
|
||||||
).permitAll()
|
|
||||||
}
|
|
||||||
http
|
http
|
||||||
.authorizeHttpRequests {
|
.authorizeHttpRequests {
|
||||||
it.requestMatchers(PathRequest.toH2Console()).permitAll()
|
it.requestMatchers(PathRequest.toH2Console()).permitAll()
|
||||||
}
|
it.requestMatchers(
|
||||||
http
|
builder.pattern("/inbox"),
|
||||||
.authorizeHttpRequests {
|
builder.pattern("/api/v1/apps"),
|
||||||
it.anyRequest().authenticated()
|
builder.pattern("/api/v1/instance/**"),
|
||||||
|
builder.pattern("/.well-known/**")
|
||||||
|
).permitAll()
|
||||||
|
it.requestMatchers(builder.pattern("/api/v1/**")).hasAnyAuthority("SCOPE_read", "SCOPE_read:accounts")
|
||||||
|
it.anyRequest().denyAll()
|
||||||
}
|
}
|
||||||
http
|
http
|
||||||
.oauth2ResourceServer {
|
.oauth2ResourceServer {
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package dev.usbharu.hideout.controller.wellknown
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
|
import dev.usbharu.hideout.domain.model.wellknown.WebFinger
|
||||||
|
import dev.usbharu.hideout.service.api.WebFingerApiService
|
||||||
|
import dev.usbharu.hideout.util.AcctUtil
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/.well-known")
|
||||||
|
class WebFingerController(
|
||||||
|
private val webFingerApiService: WebFingerApiService,
|
||||||
|
private val applicationConfig: ApplicationConfig
|
||||||
|
) {
|
||||||
|
@GetMapping("/webfinger")
|
||||||
|
suspend fun webfinger(@RequestParam resource: String): ResponseEntity<WebFinger> {
|
||||||
|
val acct = AcctUtil.parse(resource)
|
||||||
|
val user =
|
||||||
|
webFingerApiService.findByNameAndDomain(acct.username, acct.domain ?: URL(applicationConfig.url).host)
|
||||||
|
val webFinger = WebFinger(
|
||||||
|
"acct:${user.name}@${user.domain}",
|
||||||
|
listOf(
|
||||||
|
WebFinger.Link(
|
||||||
|
"self",
|
||||||
|
"application/activity+json",
|
||||||
|
applicationConfig.url + "/users/" + user.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return ResponseEntity(webFinger, HttpStatus.OK)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue