Утечки памяти при аутентификации пользователя с помощью oauth2 и keycloak (SSO)JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Утечки памяти при аутентификации пользователя с помощью oauth2 и keycloak (SSO)

Сообщение Anonymous »

Недавно мы перенесли приложение с Vaadin 14 на Vaadin 24 (Spring boot, Vaadin-flow, Java 17).
Мы используем вход keycloak+oauth2 с единым входом, как и раньше. . Это работает очень просто:
  • пользователь открывает URL-адрес www.app.com
  • мы генерируем JWK на основе нашего сертификата< /li>
    мы перенаправляем пользователя на keycloak, затем в зависимости от ролей пользователя и картографов keycloak пользователь либо вошел в систему, либо нет, логин/пароль не требуется
В предыдущей версии приложения все работало нормально, но теперь возникает утечка памяти при попытке авторизовать первого пользователя, который пытается открыть URL-адрес после запуска приложения.
Похоже, браузер постоянно пытается установить сеанс SSL, прежде чем мы создадим пользователя авторизации JWK, что вызывает эту ошибку:

Код: Выделить всё

class=o.a.t.u.n.j.JSSESupport level=DEBUG thread=https-jsse-nio-8443-exec-8 trace= login=- - Error trying to obtain a certificate from the client
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at java.base/sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:1034)
at org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(JSSESupport.java:107)
at org.apache.coyote.AbstractProcessor.populateSslRequestAttributes(AbstractProcessor.java:815)
at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:489)
at org.apache.coyote.Request.action(Request.java:523)
at org.apache.catalina.connector.Request.getAttribute(Request.java:851)
at org.apache.catalina.connector.Request.getAttributeNames(Request.java:925)
at org.apache.catalina.connector.RequestFacade.getAttributeNames(RequestFacade.java:257)
at org.springframework.web.servlet.handler.HandlerMappingIntrospector$AttributesPreservingRequest.initAttributes(HandlerMappingIntrospector.java:489)
at org.springframework.web.servlet.handler.HandlerMappingIntrospector$AttributesPreservingRequest.(HandlerMappingIntrospector.java:483)
at org.springframework.web.servlet.handler.HandlerMappingIntrospector.setCache(HandlerMappingIntrospector.java:216)
at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:193)
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74)
at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230)
class=o.a.t.u.n.N.handshake level=DEBUG thread=https-jsse-nio-8443-exec-6 trace=3de145a2ae27eb0c login=- - Handshake failed for client connection from IP address [0:0:0:0:0:0:0:1] and port [59728]
java.io.IOException: An established connection was aborted by the software in your host machine
at java.base/sun.nio.ch.SocketDispatcher.read0(Native Method)
at java.base/sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:46)
at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:330)
at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:296)
at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:259)
at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:417)
at org.apache.tomcat.util.net.SecureNioChannel.handshakeUnwrap(SecureNioChannel.java:467)
at org.apache.tomcat.util.net.SecureNioChannel.handshake(SecureNioChannel.java:214)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1716)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:842)
2024/07/08 14:49:53,547 class=o.a.t.u.n.NioEndpoint level=ERROR thread=https-jsse-nio-8443-exec-6 trace=3de145a2ae27eb0c login=- - Failed to close channel
java.io.IOException:  Invalid close state, will not send network data.
at org.apache.tomcat.util.net.SecureNioChannel.close(SecureNioChannel.java:544)
at org.apache.tomcat.util.net.SecureNioChannel.close(SecureNioChannel.java:559)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doClose(NioEndpoint.java:1212)
at org.apache.tomcat.util.net.SocketWrapperBase.close(SocketWrapperBase.java:425)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1748)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:842)
Эта ошибка возникает 3–4 раза, в результате чего массивы размером 3–4 байта застревают в памяти. Каждый занимает 1 ГБ кучи. Мы профилировали приложение с помощью JProfiler, и это результат входящих ссылок на один из байтовых массивов:
[img]https:// i.sstatic.net/BHE8cVrz.png[/img]

Я пытался отладить установление сеанса SSL, но безуспешно.
Это соответствующая конфигурация безопасности версии Vaadin 24:

Код: Выделить всё

@Configuration
@EnableWebSecurity
public class KeycloakSecurityConfig extends VaadinWebSecurity {

private OAuth2AccessTokenResponseClient getAuthorizationCodeToken() {
DefaultAuthorizationCodeTokenResponseClient authorizationCodeTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
OAuth2AuthorizationCodeGrantRequestEntityConverter oAuth2AuthorizationCodeGrantRequestEntityConverter = new OAuth2AuthorizationCodeGrantRequestEntityConverter();
oAuth2AuthorizationCodeGrantRequestEntityConverter.addParametersConverter(new NimbusJwtClientAuthenticationParametersConverter((cc) -> {
try {
Key key = keyStore.getKey(alias, keyPassword);
X509Certificate xcert = (X509Certificate) temp.getCertificate(keyId);
RSAKey rsaJWK = RSAKey.parse(xcert);
JWK jwk = new RSAKey.Builder(rsaJWK)
.keyID(keyId)
.privateKey((RSAPrivateKey) key)
.keyUse(KeyUse.SIGNATURE)
.keyStore(temp)
.build();
return jwk;
} catch (Exception e) {
log.error(e);
}
return null;
}));
authorizationCodeTokenResponseClient.setRequestEntityConverter(oAuth2AuthorizationCodeGrantRequestEntityConverter);
return authorizationCodeTokenResponseClient;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(req -> req.requestMatchers(AntPathRequestMatcher.antMatcher("/status")).permitAll());
super.configure(http);
http.headers(header -> header.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)));
http
.httpBasic(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.anonymous(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.oauth2Login(login -> login
.tokenEndpoint(endpoint -> endpoint.accessTokenResponseClient(getAuthorizationCodeToken()))
.userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig
.userAuthoritiesMapper(userAuthoritiesMapper())
.oidcUserService(userRequest -> {
return mapUser(userRequest);
})));
}
}
Утечка не увеличивается у последующих пользователей, хотя ошибки тоже появляются.
Что здесь может быть не так с настройкой?
РЕДАКТИРОВАНИЕ:
Извините, я пропустил некоторые журналы в первом сообщении, спасибо за указание на это.
Я добавил IOException в журналы - это, вероятно, вызывает утечку памяти.
При последующих входах пользователей появляется только первая ошибка о рукопожатии. «IOException» больше нет. Сборщик мусора не собирает массивы байтов, они просто остаются в памяти, как показано на снимке экрана Jprofiler. Мы получали ошибку OutOfMemoryError, но мы увеличили кучу для ее отладки.
Когда приложение запускается, размер кучи составляет около 200 МБ, затем после первого входа пользователя в систему он увеличивается до 4,4 ГБ, что определенно не является нормой. нормальное поведение.

Подробнее здесь: https://stackoverflow.com/questions/787 ... ycloak-sso
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»