Shinyproxy: Batas waktu otentikasi SAML (?) Kesalahan

Dibuat pada 15 Feb 2021  ·  6Komentar  ·  Sumber: openanalytics/shinyproxy

Halo lagi! Saat kami maju melalui pengembangan aplikasi kami menggunakan SAML, kami menemukan masalah dengan autentikasi yang tampaknya hanya terjadi jika tab dibiarkan terbuka selama beberapa waktu (belum menemukan rentang waktu yang tepat yang menyebabkan masalah tersebut) dan pengguna kemudian menyegarkan tab mereka (tidak yakin apakah jendela baru juga memicunya pada saat ini). Tampaknya setelah waktu tidak aktif ini, ShinyProxy mencoba mengautentikasi ulang, dan gagal karena suatu alasan. Satu-satunya solusi yang saya temukan adalah menghapus data situs di browser untuk IdP kami (auth.company.com). Setelah itu selesai, semuanya berjalan seperti yang diharapkan.

Ketika ini terjadi, ShinyProxy mencoba mengautentikasi berkali-kali berturut-turut (saya dapat melihat banyak panggilan balik pengalihan SAML membolak-balik di bilah URL), tetapi akhirnya gagal, dan membuang saya ke http://my.company.com/app/saml /SSO dengan kesalahan berikut:

image

Di log server, saya melihat yang berikut:

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

Sesuatu yang aneh sepertinya upaya otentikasi pertama berhasil, tetapi kemudian ShinyProxy tidak menyukainya karena suatu alasan dan mencoba lagi.


Pelacakan kesalahan penuh:

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

Solusi sederhananya adalah dengan mengklik tombol "Logout", tetapi tombol itu tidak ditampilkan di layar kesalahan SAML. Sulit untuk di-debug, karena saya tidak bisa mewujudkannya sesuai permintaan. Menurut orang dukungan IdP saya, ADFS memang mengeluarkan token yang valid di awal proses ini, sehingga tampaknya menjadi masalah lokal bagaimana ShinyProxy menangani token yang diterimanya. Saya menduga karena tab browser tidak pernah ditutup, mungkin cookie login telah kedaluwarsa dan tidak diperbarui dengan benar, tetapi saya tidak tahu apa yang saya bicarakan, jadi ambillah dengan sebutir garam.

Saya akan kembali dengan beberapa informasi yang mudah-mudahan lebih berguna ketika saya mengalami kesalahan lagi, tetapi saya ingin tahu apakah ada yang melihat ini dan punya ide tentang cara memperbaikinya?

question

Semua 6 komentar

Saya menemukan masalah berikut, yang menunjuk ke pesan kesalahan serupa yang menunjukkan ketidakcocokan antara algoritme penandatanganan SHA-1 dan SHA-256, tetapi jika itu yang terjadi dalam instalasi kami, saya tidak yakin mengapa itu akan berhasil sebagian besar waktu, tetapi kemudian gagal sebentar-sebentar setelah lama tidak aktif, jadi saya rasa ini bukan masalah saya.

Sebagai tindak lanjut, saya menyetel bagian SAML aplikasi ke DEBUG level logging, dan melihat yang berikut dari salah satu peristiwa batas waktu ini:

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

Urutan ini diulang 7 kali dalam waktu sekitar 2 detik sebelum ShinyProxy menyerah dan membuang saya ke halaman kesalahan springboot generik seperti yang ditunjukkan di atas. Dua keingintahuan:

1) org.springframework.security.authentication.CredentialsExpiredException: Authentication statement is too old to be used with value 2021-02-15T15:51:35.161Z -- ini sepertinya akar masalahnya, tapi saya tidak yakin apakah ini masalah di sisi IdP atau di sisi 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 -- tampaknya template kesalahan saya tidak dimuat dengan benar. Jika ya, saya pikir saya dapat menempatkan tautan ke halaman "logout", yang dapat diklik oleh pengguna untuk mengatur ulang sesi mereka (tidak yakin apakah itu akan berhasil, hanya firasat)

Ada ide?

Tautan yang berhubungan:

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

Tautan 2 menyarankan beberapa solusi: (1) sejajarkan maxAuthenticationAge dengan masa pakai ADFS atau (2) setel forceAuthN menjadi true

Apakah ini mungkin dari dalam konfigurasi ShinyProxy, atau apakah saya melihat build khusus yang diperlukan untuk ini?

Hai @jat255

Terima kasih atas laporan dan penelitian Anda yang ekstensif! Ini cukup kebetulan: Saya mengalami masalah yang sama persis pada salah satu penerapan kami juga. Kemarin saya menemukan solusi yang sama seperti Anda, saya hanya perlu mengujinya :)

Menyetel opsi forceAuthN memang menyelesaikan masalah di pihak kami. Satu-satunya downside yang dimiliki adalah bahwa pengguna dipaksa untuk memberikan kredensial lengkapnya lagi, sedangkan ADFS percaya bahwa kredensial pengguna masih "cukup segar". Juga, dari tautan yang Anda berikan, tampaknya beberapa IDP mengabaikan opsi ini (mis. google). Anda dapat mengaktifkan forceAuthN dengan menentukannya dalam konfigurasi saml Anda:

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

Opsi ini belum didokumentasikan di situs web kami, saya akan menanganinya.

Menentukan opsi maxAuthenticationAge belum diterapkan di ShinyProxy. Namun, karena saya melihat nilai dalam opsi ini (.misalnya menggunakan google sebagai IDP), saya akan menerapkan opsi untuk ini.

Saya juga akan mencoba memberikan perilaku yang lebih berguna jika terjadi CredentialsExpiredException .

@LEDfan terima kasih banyak atas balasan cepat Anda, dan solusinya! Saya telah menerapkan perubahan itu, tetapi sekarang saya harus menunggu 24 jam untuk melihat apakah itu berhasil :smirk: Setidaknya saya telah mengonfirmasi bahwa saya melihat ForceAuthn="true" di payload SAML, jadi opsi ini pasti berfungsi di ShinyProxy samping.

Saya pikir opsi forceAuthN tidak akan terlalu sulit bagi pengguna kami, karena sebagian besar pengguna kami menggunakan otentikasi perusahaan yang terhubung dengan manajemen kredensial Windows otomatis, sehingga mereka tidak perlu memasukkan kata sandi apa pun untuk mendapatkan akses ke Sumber daya yang dilindungi SAML. Saya akan melaporkan kembali ke sini dalam beberapa hari untuk memberi tahu Anda jika itu berhasil untuk kasus kami.

Ini tampaknya berfungsi selama beberapa hari terakhir (belum melihat kesalahan lagi), jadi saya akan melanjutkan dan menutup ini. Terima kasih lagi!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat