diff options
author | Vitaly Takmazov | 2023-01-05 11:00:50 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2023-01-05 20:58:47 +0300 |
commit | cdd03aa64548810591e043fb59a287a1b36c92ba (patch) | |
tree | 665ad1e3f1162d0be76c95a814ec4500bcf5ce55 /src/main/java/com/juick/config | |
parent | 120b26c55069f89cc60ef862514d5cf09566f348 (diff) |
ActivityPub: signed GET requests, fix Signature verification
Diffstat (limited to 'src/main/java/com/juick/config')
5 files changed, 71 insertions, 51 deletions
diff --git a/src/main/java/com/juick/config/ActivityPubClientConfig.java b/src/main/java/com/juick/config/ActivityPubClientConfig.java new file mode 100644 index 00000000..940071e7 --- /dev/null +++ b/src/main/java/com/juick/config/ActivityPubClientConfig.java @@ -0,0 +1,61 @@ +package com.juick.config; + +import java.nio.charset.StandardCharsets; + +import javax.inject.Inject; + +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.ConversionService; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.juick.model.User; +import com.juick.service.SignatureService; +import com.juick.util.ActivityPubRequestInterceptor; +import com.juick.www.api.activity.model.objects.Actor; + +@Configuration +public class ActivityPubClientConfig { + @Inject + CloseableHttpClient httpClient; + @Inject + ObjectMapper jsonMapper; + @Inject + private ActivityPubClientErrorHandler activityPubClientErrorHandler; + @Inject + private SignatureService signatureService; + @Inject + private ConversionService conversionService; + @Inject + private User serviceUser; + + @Bean + ClientHttpRequestFactory clientHttpRequestFactory() { + var clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); + clientHttpRequestFactory.setHttpClient(httpClient); + return clientHttpRequestFactory; + } + + @Bean + MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + converter.setObjectMapper(jsonMapper); + return converter; + } + + @Bean + RestTemplate restClient() { + RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory()); + restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter()); + restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8)); + restTemplate.setErrorHandler(activityPubClientErrorHandler); + restTemplate.getInterceptors().add(new ActivityPubRequestInterceptor()); + return restTemplate; + } +} diff --git a/src/main/java/com/juick/config/ActivityPubClientErrorHandler.java b/src/main/java/com/juick/config/ActivityPubClientErrorHandler.java index 243a4e32..b3aedf1f 100644 --- a/src/main/java/com/juick/config/ActivityPubClientErrorHandler.java +++ b/src/main/java/com/juick/config/ActivityPubClientErrorHandler.java @@ -18,7 +18,6 @@ package com.juick.config; import com.juick.service.activities.DeleteUserEvent; -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationEventPublisher; diff --git a/src/main/java/com/juick/config/ActivityPubConfig.java b/src/main/java/com/juick/config/ActivityPubConfig.java index 9a626d12..b18dc71c 100644 --- a/src/main/java/com/juick/config/ActivityPubConfig.java +++ b/src/main/java/com/juick/config/ActivityPubConfig.java @@ -20,29 +20,18 @@ package com.juick.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.juick.ActivityPubManager; import com.juick.KeystoreManager; -import com.juick.util.ActivityPubRequestInterceptor; import com.juick.www.WebApp; import com.juick.www.api.activity.converters.UserToActorConverter; import com.juick.www.api.activity.helpers.ProfileUriBuilder; -import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.http.converter.StringHttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.web.client.RestTemplate; import javax.inject.Inject; -import java.nio.charset.StandardCharsets; - @Configuration public class ActivityPubConfig { @Inject - ActivityPubClientErrorHandler activityPubClientErrorHandler; - @Inject ObjectMapper jsonMapper; @Inject KeystoreManager keystoreManager; @@ -52,37 +41,10 @@ public class ActivityPubConfig { private String baseUri; @Bean - MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() { - MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); - converter.setObjectMapper(jsonMapper); - return converter; - } - - @Bean ActivityPubManager activityPubManager() { return new ActivityPubManager(); } - @Inject - CloseableHttpClient httpClient; - - @Bean - ClientHttpRequestFactory clientHttpRequestFactory() { - var clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); - clientHttpRequestFactory.setHttpClient(httpClient); - return clientHttpRequestFactory; - } - - @Bean - RestTemplate apClient() { - RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory()); - restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter()); - restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8)); - restTemplate.setErrorHandler(activityPubClientErrorHandler); - restTemplate.getInterceptors().add(new ActivityPubRequestInterceptor()); - return restTemplate; - } - @Bean UserToActorConverter userToActorConverter() { return new UserToActorConverter(profileUriBuilder(), keystoreManager, webApp); diff --git a/src/main/java/com/juick/config/AppConfig.java b/src/main/java/com/juick/config/AppConfig.java index d54bc675..ff92de1f 100644 --- a/src/main/java/com/juick/config/AppConfig.java +++ b/src/main/java/com/juick/config/AppConfig.java @@ -20,6 +20,7 @@ package com.juick.config; import com.juick.*; import com.juick.model.User; import com.juick.service.HelpService; +import com.juick.service.SignatureService; import com.juick.service.StorageService; import com.juick.service.FileSystemStorageService; import com.juick.service.UserService; @@ -158,8 +159,8 @@ public class AppConfig { } @Bean - SignatureManager signatureManager() { - return new SignatureManager(); + SignatureService signatureManager() { + return new SignatureService(keystoreManager()); } @Bean diff --git a/src/main/java/com/juick/config/SecurityConfig.java b/src/main/java/com/juick/config/SecurityConfig.java index d60abe00..d3f89eef 100644 --- a/src/main/java/com/juick/config/SecurityConfig.java +++ b/src/main/java/com/juick/config/SecurityConfig.java @@ -18,7 +18,7 @@ package com.juick.config; import com.juick.KeystoreManager; -import com.juick.SignatureManager; +import com.juick.service.ActivityPubService; import com.juick.service.UserService; import com.juick.service.security.BearerTokenAuthenticationFilter; import com.juick.service.security.HTTPSignatureAuthenticationFilter; @@ -30,8 +30,6 @@ import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.ImmutableJWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -53,7 +51,6 @@ import org.springframework.security.oauth2.server.authorization.config.annotatio import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.RedirectStrategy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.*; import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices; @@ -65,7 +62,6 @@ import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import javax.inject.Inject; -import java.io.IOException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.Arrays; @@ -107,7 +103,7 @@ public class SecurityConfig { } @Inject - private SignatureManager signatureManager; + private ActivityPubService activityPubService; @Bean HashParamAuthenticationFilter apiAuthenticationFilter() { @@ -195,11 +191,11 @@ public class SecurityConfig { } @Bean - @Order(2) + @Order(Ordered.HIGHEST_PRECEDENCE + 1) SecurityFilterChain apiChain(HttpSecurity http) throws Exception { - http.securityMatcher("/api/**") + http.securityMatcher("/api/**", "/u/**", "/n/**") .addFilterBefore(apiAuthenticationFilter(), BasicAuthenticationFilter.class) - .addFilterBefore(new HTTPSignatureAuthenticationFilter(signatureManager, userService), + .addFilterBefore(new HTTPSignatureAuthenticationFilter(activityPubService, userService), BasicAuthenticationFilter.class) .authorizeHttpRequests(requests -> requests .requestMatchers(HttpMethod.OPTIONS).permitAll() @@ -210,7 +206,7 @@ public class SecurityConfig { "/api/skypebotendpoint", "/api/_fblogin", "/api/_vklogin", "/api/_tglogin", "/api/_google", "/api/_applelogin", "/api/signup", - "/api/inbox", "/api/events", "/api/u/", + "/api/inbox", "/api/events", "/u/**", "/n/**", "/api/info/**", "/api/v1/apps", "/api/v1/instance", "/api/nodeinfo/2.0", "/oauth/**") .permitAll() @@ -251,6 +247,7 @@ public class SecurityConfig { return handler; } @Bean + @Order(Ordered.HIGHEST_PRECEDENCE + 2) SecurityFilterChain wwwChain(HttpSecurity http) throws Exception { http.addFilterBefore(wwwAuthenticationFilter(), BasicAuthenticationFilter.class) .authorizeHttpRequests(authorize -> authorize |