Erudika / scoold-pro

Cloud-ready Q&A platform for the enterprise (self-hosted, on premise)
https://scoold.com
Other
7 stars 0 forks source link

Config for moderator/admin roles from the OAuth2 claim 'roles' has no effect. #58

Closed pikrakpzu closed 2 years ago

pikrakpzu commented 2 years ago

Hi,

I cannot get these parameters to work, they don't seem to be working properly: 1 para.security.oauth.groups_attribute_name 2 para.security.oauth.users_equivalent_claim_value Also, I am not able to help with source checking because this is a Scoold Pro feature.

Expected

According to the README, setting para.security.oauth.users_equivalent_claim_value parameter should block access to users who do not have the indicated role.

Observed

All users with active OIDC accounts can sign in regardless of the values of the indicated parameters. Using correct values has no effect. Using incorrect values has no effect. For example: para.security.oauth.groups_attribute_name = "sub". para.security.oauth.users_equivalent_claim_value = "XXXX" Should refuse signing for all users, but it desn't.

Versions used (docker images):

  • **.amazonaws.com/scoold-pro:1.47.2
  • erudikaltd/para:v1.43.4-base
  • erudikaltd/para-dao-mongodb:1.37.1
  • erudikaltd/para-search-elasticsearch:1.38.2
  • elasticsearch:7.17.0
  • mongo:5.0.6-focal

Used Scoold OIDC config (anonymized):

To be sure, parameters with prefix para.security.oauth.parameters. works well.

para.oa2_app_id = "client"
para.oa2_secret = "secret"
para.security.oauth.authz_url = "https://oidc.company.com/logon/oidc/authorize"
para.security.oauth.token_url = "https://oidc.company.com/logon/oidc/token"
para.security.oauth.profile_url = "https://oidc.company.com/logon/oidc/profile"
para.security.oauth.scope = "openid customattributesscope"
para.security.redirect_uri = "https://scoold.company.com"

# extra options
para.security.oauth.accept_header = ""
para.security.oauth.domain = "company.com"
para.security.oauth.parameters.id = "sub"
para.security.oauth.parameters.email = "/attributes/Email"
para.security.oauth.parameters.name = "/attributes/DisplayName"
para.security.oauth.parameters.given_name = "/attributes/FN"
para.security.oauth.parameters.family_name = "/attributes/LN"

para.security.oauth.provider = "Internal OIDC"
para.security.oauth.token_delegation_enabled = true
para.jwt_expires_after = 300

para.security.oauth.groups_attribute_name = "/attributes/MemberOf"
para.security.oauth.mods_equivalent_claim_value = "MODERATOR_SCOOLD"
para.security.oauth.admins_equivalent_claim_value = "ADMIN_SCOOLD"
para.security.oauth.users_equivalent_claim_value = "USER_SCOOLD"
para.security.oauth.download_avatars = false

OIDC content (anonymized):

{
    "sub": "username",
    "auth_time": 1531571734,
    "attributes": {
        "Office": "Full office name",
        "CN": "User Name",
        "credentialType": "Type",
        "DisplayName": "User Name (Office)",
        "DN": "uid=username,CN=Users,O=COMPANY",
        "Email": "username@company.com",
        "FN": "Firstname",
        "MemberOf": [
                                               "CN=UX_some_role,CN=UXUSER,CN=UX,CN=Groups,O=COMPANY",
                                               "CN=confluence-users,CN=CF_PROD,CN=CF,CN=Groups,O=COMPANY",
                                               "CN=wiki_space_pcpzu_edytor,CN=CF_PROD,CN=CF,CN=Groups,O=COMPANY",
                                               "CN=ADMIN_SCOOLD,CN=SCOOLD,CN=Groups,O=COMPANY",
                                               "CN=OTHER_SUPERUSER,CN=OTHER,CN=OS,CN=Groups,O=COMPANY"
        ],
        "Name": "username",
        "LN": "Lastname",
        "UID": "username"
    },
    "id": "username"
}
albogdano commented 2 years ago

Hm, this is a bit tricky to achieve because we need to drill down inside the MemberOf array to find the role mapping. But it is possible. At the moment JSON pointers like /attribute/email only work with the configuration properties para.security.oauth.parameters.*. I will try to add support for this in the next version of ParaScoold (role mapping is part of Scoold).

albogdano commented 2 years ago

Ok, this is done! It was easier than I thought. Make sure you change your configuration to use regular expressions:

para.security.oauth.groups_attribute_name = "/attributes/MemberOf"
para.security.oauth.mods_equivalent_claim_value = ".*?MODERATOR_SCOOLD.*"
para.security.oauth.admins_equivalent_claim_value = ".*?ADMIN_SCOOLD.*"
para.security.oauth.users_equivalent_claim_value = ".*?USER_SCOOLD.*"
pikrakpzu commented 2 years ago

Debug from Para:

[DEBUG] id: 6202552ce54b5b05c40cf670 row null: false
[DEBUG] DAO.read() 6202552ce54b5b05c40cf670 -> user
[DEBUG] Cache.put() scoold 6202552ce54b5b05c40cf670
[DEBUG] IndexAndCacheAspect: Cache miss: scoold->6202552ce54b5b05c40cf670
[DEBUG] Updated OAuth2 tokens for user 6202552ce54b5b05c40cf670:
idpAccessTokenPayload: 
idpIdTokenPayload: {"jti":"TGT-43296-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXoidc-pre.company.org","iss":"https://oidc-pre.company.org/login/oidc","aud":"login_preprod_oidc_client","exp":1111111111,"iat":2222222222,"nbf":3333333333,"sub":"username","amr":["AD"],"state":"scoold","nonce":"","at_hash":"xxxxxxxxxxxx_xxxxxxx","Office":"User Office","CN":"User Name (username)","DisplayName":"User Name (User Department)","DN":"uid=username,CN=Users,O=COMPANY","Email":"username@company.org","Imie":"User","MemberOf":["CN=UX_appe_prod_app_user,CN=UXUSER,CN=UX,CN=Groups,O=COMPANY","CN=appa-users,CN=APPA_PROD,CN=APPA,CN=Groups,O=COMPANY","CN=kibana_admin_prod,CN=Kibana_PROD,CN=Kibana,CN=Groups,O=COMPANY","CN=jira_employee,CN=JIRA_PROD,CN=JIRA,CN=Groups,O=COMPANY","CN=UX_eve_dev_app_user,CN=UXUSER,CN=UX,CN=Groups,O=COMPANY","CN=jenkins-syse_build_TEST,CN=TEST,CN=Jenkins-SysE,CN=Groups,O=COMPANY","CN=kubernetes_view_prod,CN=Kubernetes_PROD,CN=Kubernetes,CN=Groups,O=COMPANY","CN=USER_SCOOLD,CN=SCOOLD,CN=Groups,O=COMPANY","CN=Bibt_Users_PROD,CN=BITBUCKET_PROD,CN=BITBUCKET,CN=Groups,O=COMPANY","CN=SYS_D_SU_PREPROD,CN=SYSD_PREPROD,CN=SYSD,CN=Groups,O=COMPANY"],"WorkPlace":"777777777","Name":"username","LastName":"Name","UID":"username","preferred_username":"login_preprod_oidc_client"}
idpRefreshToken: RT-35666-XXXXXXXXXXXXXXXXXXXXXXXXXXX
[DEBUG] key: 6202552ce54b5b05c40cf670 updated count: 1
[DEBUG] DAO.update() 6202552ce54b5b05c40cf670
albogdano commented 2 years ago

Thanks - fixed in Scoold Pro 1.48.2! I had the wrong assumption that the access token is never blank once the user is successfully authenticated but I guess if we're talking about OIDC, the ID token is more important and it makes sense that an access token is missing. If it was pure OAuth2 then we need an non-blank access token.

pikrakpzu commented 2 years ago

Debug from Para (Scoold 1.48.2):

2022-02-17 23:20:24 [DEBUG] Cache.get() para Registry:GraphiteReporter
2022-02-17 23:20:24 [DEBUG] id: Registry:GraphiteReporter row null: true
2022-02-17 23:20:24 [DEBUG] row is null or empty
2022-02-17 23:20:24 [DEBUG] DAO.read() Registry:GraphiteReporter -> null
2022-02-17 23:20:54 [DEBUG] Cache.get() para app:para
2022-02-17 23:20:54 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:para
2022-02-17 23:20:54 [WARN ] request [GET http://elasticsearch:9200/para/_doc/app:para] returned 1 warnings: [299 Elasticsearch-7.17.0-bee86328705acaa9a6daede7140defd4d9ec56bd "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security."]
2022-02-17 23:20:54 [DEBUG] Cache.put() para 4ab0f726-3c74-478a-af67-0017cf9df83a
2022-02-17 23:20:54 [DEBUG] Cache.get() para 4ab0f726-3c74-478a-af67-0017cf9df83a
2022-02-17 23:20:54 [DEBUG] Cache.contains(4ab0f726-3c74-478a-af67-0017cf9df83a) true
2022-02-17 23:20:54 [DEBUG] Cache.remove() para 4ab0f726-3c74-478a-af67-0017cf9df83a
2022-02-17 23:20:58 [DEBUG] Cache.get() para scoold/oa2:username_csrf
2022-02-17 23:20:58 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:58 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:58 [DEBUG] Cache.get() scoold oa2:username
2022-02-17 23:20:58 [DEBUG] id: oa2:username row null: false
2022-02-17 23:20:58 [DEBUG] DAO.read() oa2:username -> sysprop
2022-02-17 23:20:58 [DEBUG] Cache.put() scoold oa2:username
2022-02-17 23:20:58 [DEBUG] IndexAndCacheAspect: Cache miss: scoold->oa2:username
2022-02-17 23:20:58 [DEBUG] Cache.get() scoold 620ed6e9414acc051a8df66e
2022-02-17 23:20:58 [DEBUG] IndexAndCacheAspect: Cache hit: scoold->620ed6e9414acc051a8df66e
2022-02-17 23:20:58 [DEBUG] Updated OAuth2 tokens for user 620ed6e9414acc051a8df66e:
idpAccessTokenPayload: 
idpIdTokenPayload: {"jti":"TGT-43547-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-pre.company.org","iss":"https://oidc-pre.company.org/login/oidc","aud":"login_preprod_oidc_client","exp":1111111111,"iat":2222222222,"nbf":3333333333,"sub":"username","amr":["AD"],"state":"scoold","nonce":"","at_hash":"xxxxxxxxxxxxxxxxxxxx","Office":"User Office","CN":"User Name (username)","DisplayName":"User Name (User Department)","DN":"uid=username,CN=Users,O=COMPANY","Email":"username@company.org","Imie":"User","MemberOf":["CN=UX_appe_prod_app_user,CN=UXUSER,CN=UX,CN=Groups,O=COMPANY","CN=appa-users,CN=APPA_PROD,CN=APPA,CN=Groups,O=COMPANY","CN=kibana_admin_prod,CN=Kibana_PROD,CN=Kibana,CN=Groups,O=COMPANY","CN=jira_employee,CN=JIRA_PROD,CN=JIRA,CN=Groups,O=COMPANY","CN=UX_eve_dev_app_user,CN=UXUSER,CN=UX,CN=Groups,O=COMPANY","CN=jenkins-syse_build_TEST,CN=TEST,CN=Jenkins-SysE,CN=Groups,O=COMPANY","CN=kubernetes_view_prod,CN=Kubernetes_PROD,CN=Kubernetes,CN=Groups,O=COMPANY","CN=USER_SCOOLD,CN=SCOOLD,CN=Groups,O=COMPANY","CN=Bibt_Users_PROD,CN=BITBUCKET_PROD,CN=BITBUCKET,CN=Groups,O=COMPANY","CN=SYS_D_SU_PREPROD,CN=SYSD_PREPROD,CN=SYSD,CN=Groups,O=COMPANY"],"WorkPlace":"777777777","Name":"username","LastName":"Name","UID":"username","preferred_username":"login_preprod_oidc_client"}
idpRefreshToken: RT-35554-c-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2022-02-17 23:20:58 [DEBUG] key: 620ed6e9414acc051a8df66e updated count: 1
2022-02-17 23:20:58 [DEBUG] DAO.update() 620ed6e9414acc051a8df66e
2022-02-17 23:20:58 [WARN ] request [POST http://elasticsearch:9200/_bulk?timeout=1m] returned 1 warnings: [299 Elasticsearch-7.17.0-bee86328705acaa9a6daede7140defd4d9ec56bd "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security."]
2022-02-17 23:20:58 [DEBUG] Search.indexAll() 1
2022-02-17 23:20:58 [DEBUG] IndexAndCacheAspect: Indexed scoold->620ed6e9414acc051a8df66e
2022-02-17 23:20:58 [DEBUG] Cache.put() scoold 620ed6e9414acc051a8df66e
2022-02-17 23:20:58 [DEBUG] IndexAndCacheAspect: Cache put: scoold->620ed6e9414acc051a8df66e
2022-02-17 23:20:58 [DEBUG] Set SecurityContextHolder to com.erudika.para.server.security.UserAuthentication@5da9e556
2022-02-17 23:20:58 [DEBUG] Added remember-me cookie for user 'scoold/oa2:username', expiry: 'Fri Feb 18 23:20:58 GMT 2022'
2022-02-17 23:20:58 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:58 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold oa2:username
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: scoold->oa2:username
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 620ed6e9414acc051a8df66e
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: scoold->620ed6e9414acc051a8df66e
2022-02-17 23:20:59 [WARN ] null
com.nimbusds.jose.KeyLengthException: The secret length must be at least 256 bits
    at com.nimbusds.jose.crypto.impl.MACProvider.<init>(MACProvider.java:118)
    at com.nimbusds.jose.crypto.MACVerifier.<init>(MACVerifier.java:168)
    at com.nimbusds.jose.crypto.MACVerifier.<init>(MACVerifier.java:81)
    at com.nimbusds.jose.crypto.MACVerifier.<init>(MACVerifier.java:97)
    at com.erudika.para.server.security.SecurityUtils.isValidJWToken(SecurityUtils.java:225)
    at com.erudika.para.server.security.filters.PasswordlessAuthFilter.getOrCreateUser(PasswordlessAuthFilter.java:115)
    at com.erudika.para.server.security.JWTRestfulAuthFilter.getOrCreateUser(JWTRestfulAuthFilter.java:313)
    at com.erudika.para.server.security.JWTRestfulAuthFilter.newTokenHandler(JWTRestfulAuthFilter.java:154)
    at com.erudika.para.server.security.JWTRestfulAuthFilter.doFilter(JWTRestfulAuthFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at com.erudika.para.server.security.filters.SAMLMetadataFilter.doFilter(SAMLMetadataFilter.java:104)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at com.erudika.para.server.utils.filters.ErrorFilter.doFilter(ErrorFilter.java:59)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at com.erudika.para.server.utils.filters.CORSFilter.handleNonCORS(CORSFilter.java:415)
    at com.erudika.para.server.utils.filters.CORSFilter.doFilter(CORSFilter.java:164)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.Server.handle(Server.java:516)
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:400)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:645)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:392)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
    at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
    at java.base/java.lang.Thread.run(Unknown Source)
2022-02-17 23:20:59 [DEBUG] DAO.create() 620ed6e9414acc051a8df66e
2022-02-17 23:20:59 [WARN ] request [POST http://elasticsearch:9200/_bulk?timeout=1m] returned 1 warnings: [299 Elasticsearch-7.17.0-bee86328705acaa9a6daede7140defd4d9ec56bd "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security."]
2022-02-17 23:20:59 [DEBUG] Search.indexAll() 1
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Indexed scoold->620ed6e9414acc051a8df66e
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 620ed6e9414acc051a8df66e
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache put: scoold->620ed6e9414acc051a8df66e
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 620ed6e9414acc051a8df66e
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: scoold->620ed6e9414acc051a8df66e
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 620ed6e9414acc051a8df66e:profile
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: scoold->620ed6e9414acc051a8df66e:profile
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Elasticsearch query: SearchRequest{searchType=DFS_QUERY_THEN_FETCH, indices=[scoold], indicesOptions=IndicesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, expand_wildcards_hidden=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false, ignore_throttled=true], types=[], routing='null', preference='null', requestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=null, allowPartialSearchResults=null, localClusterAlias=null, getOrCreateAbsoluteStartMillis=-1, ccsMinimizeRoundtrips=true, source={"from":0,"size":30,"query":{"bool":{"must":[{"query_string":{"query":"(properties.space:\"scooldspace:test-scope:Test Scope\" OR properties.space:\"scooldspace:lorem:Lorem\" OR properties.space:\"scooldspace:default\")","fields":[],"type":"best_fields","default_operator":"or","max_determinized_states":10000,"allow_leading_wildcard":false,"enable_position_increments":true,"fuzziness":"AUTO","fuzzy_prefix_length":0,"fuzzy_max_expansions":50,"phrase_slop":0,"escape":false,"auto_generate_synonyms_phrase_query":true,"fuzzy_transpositions":true,"boost":1.0}},{"term":{"type":{"value":"question","boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}},"sort":[{"timestamp":{"order":"desc"}}],"track_total_hits":10000}, cancelAfterTimeInterval=null}
2022-02-17 23:20:59 [WARN ] request [POST http://elasticsearch:9200/scoold/_search?typed_keys=true&max_concurrent_shard_requests=5&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true&ignore_throttled=true&search_type=dfs_query_then_fetch&batched_reduce_size=512&ccs_minimize_roundtrips=true] returned 2 warnings: [299 Elasticsearch-7.17.0-bee86328705acaa9a6daede7140defd4d9ec56bd "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security."],[299 Elasticsearch-7.17.0-bee86328705acaa9a6daede7140defd4d9ec56bd "[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consider cold or frozen tiers in place of frozen indices."]
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61fd6f81ceb64569c8a77390
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61e8bec12eceb42eee2228b5
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61e527d4cb2a8e3ee238b932
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61c1f7f563b9fc4b5d86b666
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61c1ebd563b9fc4b5d86b58b
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61bbea59bffb752d7b66cbc6
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61689a6286a9a1381a4e2490
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->613a0fa580936a035fd8fabe
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61389321d8015f2c9a37d711
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->6112721de04604372725074c
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->61116450e0460437272506fb
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->600ad0fcafbbc62f010cbe5f
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61fd6f81ceb64569c8a77390
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61e8bec12eceb42eee2228b5
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61e527d4cb2a8e3ee238b932
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61c1f7f563b9fc4b5d86b666
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61c1ebd563b9fc4b5d86b58b
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61bbea59bffb752d7b66cbc6
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61689a6286a9a1381a4e2490
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 613a0fa580936a035fd8fabe
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61389321d8015f2c9a37d711
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 6112721de04604372725074c
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61116450e0460437272506fb
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 600ad0fcafbbc62f010cbe5f
2022-02-17 23:20:59 [DEBUG] Cache.getAll() scoold 12
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll(): scoold->[61fd6f81ceb64569c8a77390, 61e8bec12eceb42eee2228b5, 61e527d4cb2a8e3ee238b932, 61c1f7f563b9fc4b5d86b666, 61c1ebd563b9fc4b5d86b58b, 61bbea59bffb752d7b66cbc6, 61689a6286a9a1381a4e2490, 613a0fa580936a035fd8fabe, 61389321d8015f2c9a37d711, 6112721de04604372725074c, 61116450e0460437272506fb, 600ad0fcafbbc62f010cbe5f]
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() will read from DB: scoold
2022-02-17 23:20:59 [DEBUG] DAO.readAll() 12
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61fd6f81ceb64569c8a77390
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61fd6f81ceb64569c8a77390
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61fd6f81ceb64569c8a77390
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61e8bec12eceb42eee2228b5
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61e8bec12eceb42eee2228b5
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61e8bec12eceb42eee2228b5
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61e527d4cb2a8e3ee238b932
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61e527d4cb2a8e3ee238b932
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61e527d4cb2a8e3ee238b932
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61c1f7f563b9fc4b5d86b666
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61c1f7f563b9fc4b5d86b666
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61c1f7f563b9fc4b5d86b666
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61c1ebd563b9fc4b5d86b58b
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61c1ebd563b9fc4b5d86b58b
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61c1ebd563b9fc4b5d86b58b
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61bbea59bffb752d7b66cbc6
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61bbea59bffb752d7b66cbc6
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61bbea59bffb752d7b66cbc6
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61689a6286a9a1381a4e2490
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61689a6286a9a1381a4e2490
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61689a6286a9a1381a4e2490
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 613a0fa580936a035fd8fabe
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 613a0fa580936a035fd8fabe
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->613a0fa580936a035fd8fabe
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61389321d8015f2c9a37d711
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61389321d8015f2c9a37d711
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61389321d8015f2c9a37d711
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 6112721de04604372725074c
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61116450e0460437272506fb
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 61116450e0460437272506fb
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->61116450e0460437272506fb
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 600ad0fcafbbc62f010cbe5f
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 600ad0fcafbbc62f010cbe5f
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->600ad0fcafbbc62f010cbe5f
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Elasticsearch query: SearchRequest{searchType=DFS_QUERY_THEN_FETCH, indices=[scoold], indicesOptions=IndicesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, expand_wildcards_hidden=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false, ignore_throttled=true], types=[], routing='null', preference='null', requestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=null, allowPartialSearchResults=null, localClusterAlias=null, getOrCreateAbsoluteStartMillis=-1, ccsMinimizeRoundtrips=true, source={"from":0,"size":30,"query":{"bool":{"must":[{"query_string":{"query":"(properties.space:\"scooldspace:test-scope:Test Scope\" OR properties.space:\"scooldspace:lorem:Lorem\" OR properties.space:\"scooldspace:default\")","fields":[],"type":"best_fields","default_operator":"or","max_determinized_states":10000,"allow_leading_wildcard":false,"enable_position_increments":true,"fuzziness":"AUTO","fuzzy_prefix_length":0,"fuzzy_max_expansions":50,"phrase_slop":0,"escape":false,"auto_generate_synonyms_phrase_query":true,"fuzzy_transpositions":true,"boost":1.0}},{"term":{"type":{"value":"sticky","boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}},"sort":[{"votes":{"order":"desc"}}],"track_total_hits":10000}, cancelAfterTimeInterval=null}
2022-02-17 23:20:59 [WARN ] request [POST http://elasticsearch:9200/scoold/_search?typed_keys=true&max_concurrent_shard_requests=5&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true&ignore_throttled=true&search_type=dfs_query_then_fetch&batched_reduce_size=512&ccs_minimize_roundtrips=true] returned 2 warnings: [299 Elasticsearch-7.17.0-bee86328705acaa9a6daede7140defd4d9ec56bd "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security."],[299 Elasticsearch-7.17.0-bee86328705acaa9a6daede7140defd4d9ec56bd "[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consider cold or frozen tiers in place of frozen indices."]
2022-02-17 23:20:59 [DEBUG] Search result: appid=scoold, scoold->5f0c57074eb8cf57fdcdfe0c
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 5f0c57074eb8cf57fdcdfe0c
2022-02-17 23:20:59 [DEBUG] Cache.getAll() scoold 1
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll(): scoold->[5f0c57074eb8cf57fdcdfe0c]
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() will read from DB: scoold
2022-02-17 23:20:59 [DEBUG] DAO.readAll() 1
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 5f0c57074eb8cf57fdcdfe0c
2022-02-17 23:20:59 [DEBUG] Cache.put() scoold 5f0c57074eb8cf57fdcdfe0c
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache miss on readAll: scoold->5f0c57074eb8cf57fdcdfe0c
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61e5287bcb2a8e3ee238b961:profile
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 6168a94e52a7ef3db03093aa:profile
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 61e52794cb2a8e3ee238b8ec:profile
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 6138cbb849f56c5357d0fd88:profile
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 6139d086e5b3317688fc9a08:profile
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 616899ef86a9a1381a4e2461:profile
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 5f0c563b4eb8cf57fdcdfdc9:profile
2022-02-17 23:20:59 [DEBUG] Cache.getAll() scoold 7
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll(): scoold->[61e5287bcb2a8e3ee238b961:profile, 6168a94e52a7ef3db03093aa:profile, 61e52794cb2a8e3ee238b8ec:profile, 6138cbb849f56c5357d0fd88:profile, 6139d086e5b3317688fc9a08:profile, 616899ef86a9a1381a4e2461:profile, 5f0c563b4eb8cf57fdcdfdc9:profile]
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() will read from DB: scoold
2022-02-17 23:20:59 [DEBUG] DAO.readAll() 1
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61e5287bcb2a8e3ee238b961:profile
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 6168a94e52a7ef3db03093aa:profile
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 61e52794cb2a8e3ee238b8ec:profile
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 6138cbb849f56c5357d0fd88:profile
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 6139d086e5b3317688fc9a08:profile
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 616899ef86a9a1381a4e2461:profile
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 5f0c563b4eb8cf57fdcdfdc9:profile
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para app:scoold
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache hit: para->app:scoold
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() para CedAvKcxJN4VbzioXgnRig==_csrf
2022-02-17 23:20:59 [DEBUG] Cache.get() scoold 5f0c563b4eb8cf57fdcdfdc9:profile
2022-02-17 23:20:59 [DEBUG] Cache.getAll() scoold 1
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll(): scoold->[5f0c563b4eb8cf57fdcdfdc9:profile]
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() will read from DB: scoold
2022-02-17 23:20:59 [DEBUG] DAO.readAll() 0
2022-02-17 23:20:59 [DEBUG] IndexAndCacheAspect: Cache getAll() got from DB: 5f0c563b4eb8cf57fdcdfdc9:profile
albogdano commented 2 years ago

Possible root cause: Erudika/para@e1604f71f8e13eee72eea18ebf23e9b6474f735b

albogdano commented 2 years ago

Should we close this now @pikrakpzu?

albogdano commented 2 years ago

There seems to be a difference in what you have given as OIDC content above and what's actually returned in the ID token. The OIDC data in your example is nested inside the attributes property, whereas the the ID token has no such property and the path to MemberOf is different, i.e. /MemberOf instead of /attributes/MemberOf.

{
    "jti": "TGT-43547-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-pre.company.org",
    "iss": "https://oidc-pre.company.org/login/oidc",
    "aud": "login_preprod_oidc_client",
    "exp": 1111111111,
    "iat": 2222222222,
    "nbf": 3333333333,
    "sub": "username",
    "amr":
    [
        "AD"
    ],
    "state": "scoold",
    "nonce": "",
    "at_hash": "xxxxxxxxxxxxxxxxxxxx",
    "Office": "User Office",
    "CN": "User Name (username)",
    "DisplayName": "User Name (User Department)",
    "DN": "uid=username,CN=Users,O=COMPANY",
    "Email": "username@company.org",
    "Imie": "User",
    "MemberOf":
    [
        "CN=USER_SCOOLD,CN=SCOOLD,CN=Groups,O=COMPANY",
        "CN=SYS_D_SU_PREPROD,CN=SYSD_PREPROD,CN=SYSD,CN=Groups,O=COMPANY"
    ],
    "WorkPlace": "777777777",
    "Name": "username",
    "LastName": "Name",
    "UID": "username",
    "preferred_username": "login_preprod_oidc_client"
}

So, perhaps you could try with para.security.oauth.groups_attribute_name = "/MemberOf"?

pikrakpzu commented 2 years ago

I've ran a few tests with:

In all cases Scoold have failed to lock oidc signin, when required user clam desn't exist: .*?USER_xxx_SCOOLD.*. User has role that matches with admin claim: .*?USER_SCOOLD.*, but he didn't get admin rights.

I think that when groups_attribute_name, users_equivalent_claim_value are set and they cann't be found in OIDC auth tokens, all signin requests trough OIDC should be denied. Otherwise there is a potential risk that missconfiguration or change in OIDC could lead to unauthorized access.

albogdano commented 2 years ago

I'm happy to say that I finally was able to reproduce the issue and fix it. The tests which should pass are:

If user is not part of the USER_SCOOLD group, they will be denied access. Please update both Para (1.45.8) and Scoold (1.49.3).