Shinyproxy: خطأ مهلة مصادقة SAML (؟)

تم إنشاؤها على ١٥ فبراير ٢٠٢١  ·  6تعليقات  ·  مصدر: openanalytics/shinyproxy

مرحبا مجددا! أثناء تقدمنا ​​في تطوير تطبيقنا باستخدام SAML ، وجدنا مشكلة في المصادقة يبدو أنها تحدث فقط إذا تُركت علامة تبويب مفتوحة لبعض الوقت (لم نحدد النطاق الزمني الدقيق الذي يسبب المشكلة) ثم يقوم المستخدم بتحديث علامة التبويب الخاصة به (لست متأكدًا مما إذا كانت هناك نافذة جديدة تشغله أيضًا في هذه المرحلة). يبدو أنه بعد هذا الوقت من عدم النشاط ، يحاول ShinyProxy إعادة المصادقة ، ولكنه يفشل لسبب ما. الحل الوحيد الذي وجدته هو مسح بيانات الموقع في المتصفح لموفر الهوية (auth.company.com). بمجرد القيام بذلك ، تعمل الأشياء كما هو متوقع.

عندما يحدث هذا ، يحاول ShinyProxy المصادقة عدة مرات متتالية (يمكنني رؤية العديد من عمليات إعادة توجيه إعادة توجيه SAML تتنقل عبر شريط عنوان URL) ، لكنها تفشل في النهاية ، وتنتقل إلى http://my.company.com/app/saml / SSO مع الخطأ التالي:

image

أرى في سجلات الخادم ما يلي:

shinyproxy-server_1  | 2021-02-15 04:00:11.531  INFO 1 --- [  XNIO-1 task-4] o.s.security.saml.log.SAMLDefaultLogger  : AuthNRequest;SUCCESS;XXX.XX.XX.XXX;https://my.company.com/app;http://auth.company.com/adfs/services/trust;;;
shinyproxy-server_1  | 2021-02-15 04:00:11.608  INFO 1 --- [  XNIO-1 task-4] colMessageXMLSignatureSecurityPolicyRule : Validation of protocol message signature succeeded, message type: {urn:oasis:names:tc:SAML:2.0:protocol}Response
shinyproxy-server_1  | 2021-02-15 04:00:11.609  INFO 1 --- [  XNIO-1 task-4] o.s.security.saml.log.SAMLDefaultLogger  : AuthNResponse;FAILURE;XXX.XX.XX.XXX;https://my.company.com/app;http://auth.company.com/adfs/services/trust;;;org.springframework.security.saml.SAMLStatusException: Response has invalid status code urn:oasis:names:tc:SAML:2.0:status:Responder, status message is null

شيء غريب هو أنه يبدو أن محاولة المصادقة الأولى نجحت ، ولكن بعد ذلك لم تعجب ShinyProxy لسبب ما وحاول مرة أخرى.


تتبع الخطأ الكامل:

~shinyproxy-server_1 |
في org.springframework.security.saml.SAMLAuthenticationProvider.authenticate (SAMLAuthenticationProvider.java:88)shinyproxy-server_1 |
في org.springframework.security.authentication.ProviderManager.authenticate (ProviderManager.java:219)shinyproxy-server_1 |
في sun.reflect.GeneratedMethodAccessor63.invoke (مصدر غير معروف)shinyproxy-server_1 |
في java.lang.reflect.Method.invoke (Method.java:498)shinyproxy-server_1 |
في org.springframework.aop.framework.JdkDynamicAopProxy.invoke (JdkDynamicAopProxy.java:205)shinyproxy-server_1 |
في org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication (SAMLProcessingFilter.java:92)shinyproxy-server_1 |
في org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334)shinyproxy-server_1 |
في org.springframework.security.web.FilterChainProxy.doFilter (FilterChainProxy.java:186)shinyproxy-server_1 |
في org.springframework.security.web.authentication.
في org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119)shinyproxy-server_1 |
في org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter (AbstractAuthenticationProcessingFilter.java:200)shinyproxy-server_1 |
في org.springframework.security.web.authentication.logout.LogoutFilter.doFilter (LogoutFilter.java:116)shinyproxy-server_1 |
في org.springframework.security.web.csrf.CsrfFilter.doFilterInternal (CsrfFilter.java:117)shinyproxy-server_1 |
في org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334)shinyproxy-server_1 |
في org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal (HeaderWriterFilter.java:77)shinyproxy-server_1 |
في org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334)shinyproxy-server_1 |
في org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334)shinyproxy-server_1 |
في org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119)shinyproxy-server_1 |
في org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter (MetadataGeneratorFilter.java:87)shinyproxy-server_1 |
في org.springframework.security.web.FilterChainProxy.doFilterInternal (FilterChainProxy.java:215)shinyproxy-server_1 |
في org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:358)shinyproxy-server_1 |
على io.undertow.servlet.core.ManagedFilter.doFilter (ManagedFilter.java:61)shinyproxy-server_1 |
في org.springframework.web.filter.RequestContextFilter.doFilterInternal (RequestContextFilter.java:100)shinyproxy-server_1 |
على io.undertow.servlet.core.ManagedFilter.doFilter (ManagedFilter.java:61)shinyproxy-server_1 |
في org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal (WebMvcMetricsFilter.java:93)shinyproxy-server_1 |
على io.undertow.servlet.core.ManagedFilter.doFilter (ManagedFilter.java:61)shinyproxy-server_1 |
في org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:201)shinyproxy-server_1 |
على io.undertow.servlet.core.ManagedFilter.doFilter (ManagedFilter.java:61)shinyproxy-server_1 |
على io.undertow.servlet.handlers.FilterHandler.handleRequest (FilterHandler.java:84)shinyproxy-server_1 |
على io.undertow.servlet.handlers.ServletChain $ 1.handleRequest (ServletChain.java:68)shinyproxy-server_1 |
في io.undertow.server.handlers.PathHandler.handleRequest (PathHandler.java:91)shinyproxy-server_1 |
على io.undertow.servlet.handlers.RedirectDirHandler.handleRequest (RedirectDirHandler.java:68)shinyproxy-server_1 |
في io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest (ServletAuthenticationCallHandler.java:57)shinyproxy-server_1 |
في io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest (AbstractConfidentialityHandler.java:46)shinyproxy-server_1 |
في io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest (AuthenticationMechanismsHandler.java:60)shinyproxy-server_1 |
في io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest (AbstractSecurityContextAssociationHandler.java:43)shinyproxy-server_1 |
على io.undertow.server.handlers.PredicateHandler.handleRequest (PredicateHandler.java:43)shinyproxy-server_1 |
في io.undertow.servlet.handlers.ServletInitialHandler.access 100 دولار (ServletInitialHandler.java:78)shinyproxy-server_1 |
على io.undertow.servlet.handlers.ServletInitialHandler 2. call (ServletInitialHandler.java:130)shinyproxy-server_1 |
على io.undertow.servlet.core.ContextClassLoaderSetupAction $ 1.call (ContextClassLoaderSetupAction.java:43)shinyproxy-server_1 |
في io.undertow.servlet.handlers.ServletInitialHandler.access 000 دولار (ServletInitialHandler.java:78)shinyproxy-server_1 |
على io.undertow.server.Connectors.executeRootHandler (Connectors.java:370)shinyproxy-server_1 |
في org.jboss.threads.ContextClassLoaderSavingRunnable.run (ContextClassLoaderSavingRunnable.java:35)shinyproxy-server_1 |
في org.jboss.threads.EnhancedQueueExecutor $ ThreadBody.doRunTask (EnhancedQueueExecutor.java:1558)shinyproxy-server_1 |
في java.lang.Thread.run (Thread.java:748)~

سيكون الحل البسيط هو النقر فوق الزر "تسجيل الخروج" ، ولكن هذا الزر لا يظهر على شاشة خطأ SAML. من الصعب تصحيح الأخطاء ، لأنني لا أستطيع تحقيق ذلك عند الطلب. وفقًا لشخص دعم IdP الخاص بي ، تصدر ADFS بالفعل رمزًا مميزًا صالحًا في بداية هذه العملية ، لذلك يبدو أنها مشكلة محلية تتعلق بكيفية تعامل ShinyProxy مع الرمز المميز الذي تتلقاه. أظن أن علامة تبويب المتصفح لم تغلق أبدًا ، فربما انتهت صلاحية ملف تعريف ارتباط تسجيل الدخول ولم يتم تجديده بشكل صحيح ، لكن ليس لدي أي فكرة عما أتحدث عنه ، لذا خذ ذلك بحذر.

سأعود ببعض المعلومات المفيدة التي آمل أن أواجهها عندما يحدث الخطأ مرة أخرى ، لكنني كنت أشعر بالفضول لمعرفة ما إذا كان أي شخص قد شاهد هذا ولديه أي أفكار حول كيفية إصلاحه؟

question

ال 6 كومينتر

لقد وجدت المشكلة التالية ، التي تشير إلى وجود رسائل خطأ مشابهة تشير إلى عدم تطابق بين خوارزميات توقيع SHA-1 و SHA-256 ، ولكن إذا كان هذا هو الحال في التثبيت ، فلست متأكدًا من سبب نجاحها في معظم الأوقات ، ولكن بعد ذلك أفشل بشكل متقطع بعد فترة طويلة من عدم النشاط ، لذلك لا أعتقد أن هذه هي مشكلتي.

على سبيل المتابعة ، قمت بتعيين جزء SAML من التطبيق على تسجيل مستوى DEBUG ، ورأيت ما يلي من أحد أحداث المهلة هذه:

shinyproxy-server_1  | 2021-02-15 21:03:14.050 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.s.context.SAMLContextProviderImpl  : No IDP specified, using default http://auth.company.com/adfs/services/trust
shinyproxy-server_1  | 2021-02-15 21:03:14.050 DEBUG 1 --- [  XNIO-1 task-2] o.s.security.saml.util.SAMLUtil          : Index for AssertionConsumerService not specified, returning default
shinyproxy-server_1  | 2021-02-15 21:03:14.051 DEBUG 1 --- [  XNIO-1 task-2] o.s.security.saml.SAMLEntryPoint         : Processing SSO using WebSSO profile
shinyproxy-server_1  | 2021-02-15 21:03:14.051 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.saml.websso.WebSSOProfileImpl      : Using default consumer service with binding urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
shinyproxy-server_1  | 2021-02-15 21:03:14.052 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.saml.storage.HttpSessionStorage    : Storing message a17g5ahbxxxxxxxxxxx454jj to session hxxxxxxJ_E8xxxxxxxxHP_TwIxxxxxxxH
shinyproxy-server_1  | 2021-02-15 21:03:14.053  INFO 1 --- [  XNIO-1 task-2] o.s.security.saml.log.SAMLDefaultLogger  : AuthNRequest;SUCCESS;XXX.XX.XXX.XX;https://my.company.com/app;http://auth.company.com/adfs/services/trust;;;
shinyproxy-server_1  | 2021-02-15 21:03:14.805 DEBUG 1 --- [  XNIO-1 task-2] o.s.security.saml.SAMLProcessingFilter   : Request is to process authentication
shinyproxy-server_1  | 2021-02-15 21:03:14.806 DEBUG 1 --- [  XNIO-1 task-2] o.s.security.saml.SAMLProcessingFilter   : Attempting SAML2 authentication using profile urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser
shinyproxy-server_1  | 2021-02-15 21:03:14.811 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.saml.processor.SAMLProcessorImpl   : Retrieving message using binding urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
shinyproxy-server_1  | 2021-02-15 21:03:14.816  INFO 1 --- [  XNIO-1 task-2] colMessageXMLSignatureSecurityPolicyRule : SAML protocol message was not signed, skipping XML signature processing
shinyproxy-server_1  | 2021-02-15 21:03:14.816 DEBUG 1 --- [  XNIO-1 task-2] o.s.security.saml.util.SAMLUtil          : Found endpoint org.opensaml.saml2.metadata.impl.AssertionConsumerServiceImpl<strong i="7">@6531c789</strong> for request URL https://my.company.com/app/saml/SSO based on location attribute in metadata
shinyproxy-server_1  | 2021-02-15 21:03:14.816 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.saml.storage.HttpSessionStorage    : Message a17g5ahb0gieeh9b4e48ff6a3d454jj found in session hXmYJ_E8wf6F2plFsHP_TwIZS1Cg6n2Vu4wD4i2H, clearing
shinyproxy-server_1  | 2021-02-15 21:03:14.817 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.s.w.WebSSOProfileConsumerImpl      : Verifying issuer of the Response
shinyproxy-server_1  | 2021-02-15 21:03:14.817 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.s.w.WebSSOProfileConsumerImpl      : Verifying signature
shinyproxy-server_1  | 2021-02-15 21:03:14.820 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.s.t.MetadataCredentialResolver     : Added 1 credentials resolved from metadata of entity http://auth.company.com/adfs/services/trust
shinyproxy-server_1  | 2021-02-15 21:03:14.826 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.s.w.WebSSOProfileConsumerImpl      : Processing Bearer subject confirmation
shinyproxy-server_1  | 2021-02-15 21:03:14.836 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.s.w.WebSSOProfileConsumerImpl      : Validation of authentication statement in assertion failed, skipping
shinyproxy-server_1  | org.springframework.security.authentication.CredentialsExpiredException: Authentication statement is too old to be used with value 2021-02-15T15:51:35.161Z
                        ...
shinyproxy-server_1  | 2021-02-15 21:03:14.839 DEBUG 1 --- [  XNIO-1 task-2] o.s.s.saml.SAMLAuthenticationProvider    : Error validating SAML message
shinyproxy-server_1  |
shinyproxy-server_1  | org.opensaml.common.SAMLException: Response doesn't have any valid assertion which would pass subject validation
                       ...
shinyproxy-server_1  |
shinyproxy-server_1  | 2021-02-15 21:03:14.841  INFO 1 --- [  XNIO-1 task-2] o.s.security.saml.log.SAMLDefaultLogger  : AuthNResponse;FAILURE;XXX.XX.XXX.XX;https://my.company.com/app;http://auth.company.com/adfs/services/trust;;;org.opensaml.common.SAMLException: Response doesn't have any valid assertion which would pass subject validation
shinyproxy-server_1  |  at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:265)
                       ...
shinyproxy-server_1  |
shinyproxy-server_1  | 2021-02-15 21:03:14.842  INFO 1 --- [  XNIO-1 task-2] e.o.containerproxy.service.UserService   : Authentication failure [user: ] [error: Error validating SAML message]
shinyproxy-server_1  | 2021-02-15 21:03:14.848 DEBUG 1 --- [  XNIO-1 task-2] o.s.security.saml.SAMLProcessingFilter   : Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message
shinyproxy-server_1  |
shinyproxy-server_1  | org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message
                       ...
shinyproxy-server_1  |
shinyproxy-server_1  | 2021-02-15 21:03:14.849 DEBUG 1 --- [  XNIO-1 task-2] o.s.security.saml.SAMLProcessingFilter   : Updated SecurityContextHolder to contain null Authentication
shinyproxy-server_1  | 2021-02-15 21:03:14.849 DEBUG 1 --- [  XNIO-1 task-2] o.s.security.saml.SAMLProcessingFilter   : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler<strong i="8">@19dec0b4</strong>
shinyproxy-server_1  | 2021-02-15 21:03:14.858 ERROR 1 --- [  XNIO-1 task-2] org.thymeleaf.TemplateEngine             : [THYMELEAF][XNIO-1 task-2] Exception processing template "/": Error resolving template [/], template might not exist or might not be accessible by any of the configured Template Resolvers
shinyproxy-server_1  | org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/], template might not exist or might not be accessible by any of the configured Template Resolvers
                       ...
shinyproxy-server_1  |
shinyproxy-server_1  | 2021-02-15 21:03:14.861 ERROR 1 --- [  XNIO-1 task-2] io.undertow.request                      : UT005023: Exception handling request to /app/error
shinyproxy-server_1  |
shinyproxy-server_1  | org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/], template might not exist or might not be accessible by any of the configured Template Resolvers

يتكرر هذا التسلسل 7 مرات في حوالي ثانيتين قبل أن يستسلم ShinyProxy ويقيل لي إلى صفحة خطأ springboot العامة كما هو موضح أعلاه. فضولان:

1) org.springframework.security.authentication.CredentialsExpiredException: Authentication statement is too old to be used with value 2021-02-15T15:51:35.161Z - يبدو أن هذا هو أصل المشكلة ، لكنني لست متأكدًا مما إذا كانت هذه مشكلة من جانب IdP أو من جانب ShinyProxy

2) 2021-02-15 21:03:14.861 ERROR 1 --- [ XNIO-1 task-2] io.undertow.request : UT005023: Exception handling request to /app/error - يبدو أن قالب الخطأ الخاص بي لا يتم تحميله بشكل صحيح. إذا كان الأمر كذلك ، أعتقد أنه يمكنني وضع رابط إلى صفحة "تسجيل الخروج" ، والتي يمكن للمستخدمين النقر عليها لإعادة ضبط الجلسة الخاصة بهم (لست متأكدًا مما إذا كان ذلك سينجح أم لا ، فقط حدس)

أيه أفكار؟

روابط ذات علاقة:

1) https://stackoverflow.com/questions/48289763/spring-security-infinite-loop-after-initial-login-and-timeout
2) https://stackoverflow.com/questions/30528636/idp-initiated-saml-login-error-authentication-statement-is-too-old-to-be-used

يقترح الرابط 2 حلين: (1) محاذاة maxAuthenticationAge مع عمر ADFS أو (2) اضبط forceAuthN على true

هل هذه ممكنة من داخل تكوين ShinyProxy ، أم أني أبحث عن بناء مخصص ضروري لهذا؟

مرحبًا @ jat255

شكرا لك على التقرير والبحث الشامل الخاص بك! هذه مصادفة تمامًا: لقد واجهت نفس المشكلة بالضبط في إحدى عمليات النشر لدينا أيضًا. بالأمس وجدت نفس الحلول مثلك ، كان علي فقط اختبارها :)

إن تعيين الخيار forceAuthN يحل المشكلة بالفعل من جانبنا. الجانب السلبي الوحيد لهذا هو أن المستخدم مجبر على تقديم بيانات اعتماده الكاملة مرة أخرى ، بينما يعتقد ADFS أن بيانات اعتماد المستخدم لا تزال "حديثة بما فيه الكفاية". أيضًا ، من الرابط الذي قدمته ، يبدو أن بعض النازحين يتجاهلون هذا الخيار (مثل google). يمكنك تمكين forceAuthN بتحديده في تكوين saml الخاص بك:

proxy:
  saml:
    idp-metadata-url: ... 
    ....
    force-authn: true

لم يتم توثيق هذا الخيار بعد على موقعنا الإلكتروني ، وسأعتني بذلك.

تحديد الخيار maxAuthenticationAge لم يتم تنفيذه بعد في ShinyProxy. ومع ذلك ، بما أنني أرى قيمة في هذا الخيار (.eg باستخدام google كـ IDP) ، سأقوم بتنفيذ خيار لذلك.

سأحاول أيضًا تقديم سلوك أكثر فائدة في حالة CredentialsExpiredException .

LEDfan شكرًا جزيلاً على ردك السريع والحل! لقد قمت بتنفيذ هذا التغيير ، لكن الآن يجب أن أنتظر 24 ساعة لمعرفة ما إذا كان يعمل: ابتسامة: لقد أكدت على الأقل أنني أرى ForceAuthn="true" في حمولة SAML ، لذلك يعمل الخيار بالتأكيد على ShinyProxy الجانب.

أعتقد أن الخيار forceAuthN لن يكون صعبًا جدًا على مستخدمينا ، نظرًا لأن معظم مستخدمينا يستخدمون مصادقة المؤسسة المرتبطة بإدارة بيانات اعتماد Windows التلقائية ، لذلك لا يتعين عليهم إدخال أي كلمات مرور للوصول إلى الموارد المحمية بواسطة SAML. سأبلغك هنا في غضون أيام قليلة لإعلامك بما إذا كانت تعمل في حالتنا.

يبدو أن هذا يعمل خلال الأيام القليلة الماضية (لم أر الخطأ مرة أخرى) ، لذلك سأمضي قدمًا وأغلق هذا الأمر. شكرا لك مرة أخرى!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات