diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt index 589dc701..a09dbd43 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt @@ -12,10 +12,10 @@ import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.annotation.Order -import org.springframework.http.MediaType import org.springframework.security.config.Customizer 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.reactive.EnableWebFluxSecurity import org.springframework.security.core.Authentication import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder 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.authentication.LoginUrlAuthenticationEntryPoint 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 java.security.KeyPairGenerator import java.security.interfaces.RSAPrivateKey @@ -36,6 +35,7 @@ import java.security.interfaces.RSAPublicKey import java.util.* @EnableWebSecurity(debug = true) +@EnableWebFluxSecurity() @Configuration class SecurityConfig { @@ -47,9 +47,8 @@ class SecurityConfig { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http) http .exceptionHandling { - it.defaultAuthenticationEntryPointFor( - LoginUrlAuthenticationEntryPoint("/login"), - MediaTypeRequestMatcher(MediaType.TEXT_HTML) + it.authenticationEntryPoint( + LoginUrlAuthenticationEntryPoint("/login") ) } .oauth2ResourceServer { @@ -58,29 +57,23 @@ class SecurityConfig { return http.build() } + @Bean @Order(2) fun defaultSecurityFilterChain(http: HttpSecurity, introspector: HandlerMappingIntrospector): SecurityFilterChain { 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 .authorizeHttpRequests { it.requestMatchers(PathRequest.toH2Console()).permitAll() - } - http - .authorizeHttpRequests { - it.anyRequest().authenticated() + it.requestMatchers( + builder.pattern("/inbox"), + builder.pattern("/api/v1/apps"), + 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 .oauth2ResourceServer { diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/wellknown/WebFingerController.kt b/src/main/kotlin/dev/usbharu/hideout/controller/wellknown/WebFingerController.kt new file mode 100644 index 00000000..2542f5d8 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/wellknown/WebFingerController.kt @@ -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 { + 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) + } +}