Hi,
I freshly installed SAS Viya 3.5 on IBM Power (single-node), setup an LDAP, see the users in SAS Viya interface but can't use them for login. I guess there's something wrong with my LDAP config but can't figure it out and didn't find an example of what it should look like.
Here are the details:
1. LDAP
OpenLDAP 2.4.44 started as a service on the same node SAS Viya is installed on
Content: 1 single 'mdeloche' user without any groups
[root@svtvm1 ~]# ldapsearch -x -b "dc=example,dc=com" # extended LDIF # # LDAPv3 # base <dc=example,dc=com> with scope subtree # filter: (objectclass=*) # requesting: ALL # # example.com dn: dc=example,dc=com objectClass: dcObject objectClass: organization dc: example o: example # users, example.com dn: ou=users,dc=example,dc=com objectClass: organizationalUnit ou: users # groups, example.com dn: ou=groups,dc=example,dc=com objectClass: organizationalUnit ou: groups # mdeloche, users, example.com dn: cn=mdeloche,ou=users,dc=example,dc=com cn: mdeloche sn: mdeloche objectClass: inetOrgPerson userPassword:: HashOfThePassword
uid: mdeloche # search result search: 2 result: 0 Success # numResponses: 5 # numEntries: 4 [root@svtvm1 ~]#
Config:
[root@svtvm1 ~]# ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config olcDatabase=\* SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 # extended LDIF # # LDAPv3 # base <cn=config> with scope subtree # filter: olcDatabase=* # requesting: ALL # # {-1}frontend, config dn: olcDatabase={-1}frontend,cn=config objectClass: olcDatabaseConfig objectClass: olcFrontendConfig olcDatabase: {-1}frontend # {0}config, config dn: olcDatabase={0}config,cn=config objectClass: olcDatabaseConfig olcDatabase: {0}config olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external ,cn=auth" manage by * none # {1}monitor, config dn: olcDatabase={1}monitor,cn=config objectClass: olcDatabaseConfig olcDatabase: {1}monitor olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external , cn=auth" read by dn.base="cn=admin,dc=example,dc=com" read by * none # {2}hdb, config dn: olcDatabase={2}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {2}hdb olcDbDirectory: /var/lib/ldap olcDbIndex: objectClass eq,pres olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub olcSuffix: dc=example,dc=com olcRootDN: cn=admin,dc=example,dc=com olcRootPW: {SSHA}HashOfTheAdminPassword # search result search: 2 result: 0 Success # numResponses: 5 # numEntries: 4
2. SAS Viya config
sas.identities.providers.ldap.connection:
Services: Identities service, SAS Logon Manager anonymousBind: off customEnvironmentProperties: (none) host: localhost password: (admin password) pool.enabled: on pool.evictionTimePeriodMillis: 240,000 pool.idleTimeMillis: 480,000 pool.maxActive: 8 pool.maxIdle: 8 pool.maxSize: -1 pool.maxWait: 30,000 pool.minIdle: 0 pool.testOnBorrow: on pool.testOnReturn: off pool.testWhileIdle: on pool.whenExhaustedAction: 1 port: 389 startTLS.mode: none url: ldap://${sas.identities.providers.ldap.connection.host}:${sas.identities.providers.ldap.connection.port} userDN: cn=admin,dc=example,dc=com
sas.identities.providers.ldap.user:
Services: Identities service, SAS Logon Manager accountId: uid [many useless fields omitted...] baseDN: ou=users,dc=example,dc=com distinguishedName: dn name: cn objectClass: objectClass objectFilter: (objectClass=inetOrgPerson) searchFilter: (${sas.identities.providers.ldap.user.objectFilter})
I successfully see the 'mdeloche' user in the SAS Viya 'Users' list, which means my LDAP is successfully reached and queried.
I added 'mdeloche' to the 'SAS Administrators' group but when I try to login using that user/password, I get "The user ID or password is not valid".
Here is content of the 'identities' log file in /var/log/sas/viya when I try to login:
Oct 13 16:06:27 svtvm1.localdomain slapd[37669]: conn=1151 fd=23 ACCEPT from IP=127.0.0.1:57636 (IP=0.0.0.0:389) Oct 13 16:06:27 svtvm1.localdomain slapd[37669]: conn=1151 op=0 BIND dn="cn=admin,dc=example,dc=com" method=128 Oct 13 16:06:27 svtvm1.localdomain slapd[37669]: conn=1151 op=0 BIND dn="cn=admin,dc=example,dc=com" mech=SIMPLE ssf=0 Oct 13 16:06:27 svtvm1.localdomain slapd[37669]: conn=1151 op=0 RESULT tag=97 err=0 text= Oct 13 16:06:27 svtvm1.localdomain slapd[37669]: conn=1151 op=1 UNBIND Oct 13 16:06:27 svtvm1.localdomain slapd[37669]: conn=1151 fd=23 closed
And probably more relevant, in the 'saslogon' log, the following Java error:
2020-10-13 16:06:27.971 ERROR 273655 --- [0-auto-1-exec-8] w.a.UsernamePasswordAuthenticationFilter : service [0ca54bddb77d1e1a] An internal error occurred while trying to authenticate the user. org.springframework.security.authentication.InternalAuthenticationServiceException: invalid attribute description; nested exception is javax.naming.directory.InvalidSearchFilterException: invalid attribute description; remaining name 'ou=users,dc=example,dc=com' at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:206) at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:85) at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175) at org.cloudfoundry.identity.uaa.authentication.manager.ChainedAuthenticationManager.authenticate(ChainedAuthenticationManager.java:81) at org.cloudfoundry.identity.uaa.authentication.manager.DynamicLdapAuthenticationManager.authenticate(DynamicLdapAuthenticationManager.java:107) at org.cloudfoundry.identity.uaa.authentication.manager.ChainedAuthenticationManager.authenticate(ChainedAuthenticationManager.java:81) at org.cloudfoundry.identity.uaa.authentication.manager.DynamicZoneAwareAuthenticationManager.authenticate(DynamicZoneAwareAuthenticationManager.java:71) at com.sas.logon.authentication.manager.DynamicZoneAwareAuthenticationManager.authenticate(DynamicZoneAwareAuthenticationManager.java:72) at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:200) at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.authentication.PasswordChangeUiRequiredFilter.doFilterInternal(PasswordChangeUiRequiredFilter.java:60) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.saml.SAMLLogoutFilter.processLogout(SAMLLogoutFilter.java:168) at org.springframework.security.saml.SAMLLogoutFilter.doFilter(SAMLLogoutFilter.java:110) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.mfa.MfaUiRequiredFilter.doFilter(MfaUiRequiredFilter.java:78) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.web.UaaSavedRequestCache.doFilter(UaaSavedRequestCache.java:62) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at com.sas.logon.web.CsrfCookieCleanupFilter.doFilterInternal(CsrfCookieCleanupFilter.java:46) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:155) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at com.sas.logon.provider.guest.GuestAccessFilter.doFilter(GuestAccessFilter.java:102) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.authentication.ReAuthenticationRequiredFilter.doFilterInternal(ReAuthenticationRequiredFilter.java:35) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:209) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.provider.saml.idp.IdpMetadataGeneratorFilter.doFilter(IdpMetadataGeneratorFilter.java:89) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.security.web.HttpsHeaderFilter.doFilter(HttpsHeaderFilter.java:37) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.security.web.SecurityFilterChainPostProcessor$UaaLoggingFilter.doFilter(SecurityFilterChainPostProcessor.java:255) at org.cloudfoundry.identity.uaa.security.web.SecurityFilterChainPostProcessor$HttpsEnforcementFilter.doFilter(SecurityFilterChainPostProcessor.java:198) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.oauth.DisableIdTokenResponseTypeFilter.doFilterInternal(DisableIdTokenResponseTypeFilter.java:86) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at com.sas.logon.zone.IdentityZoneResolvingFilter.doFilterInternal(IdentityZoneResolvingFilter.java:77) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.web.LimitedModeUaaFilter.doFilterInternal(LimitedModeUaaFilter.java:85) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:97) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.authentication.UTF8ConversionFilter.validateParamsAndContinue(UTF8ConversionFilter.java:75) at org.cloudfoundry.identity.uaa.authentication.UTF8ConversionFilter.doFilter(UTF8ConversionFilter.java:59) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.web.HeaderFilter.doFilter(HeaderFilter.java:52) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.metrics.UaaMetricsFilter.doFilterInternal(UaaMetricsFilter.java:87) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:151) at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:86) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter.doFilter(ExceptionLoggingFilter.java:50) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at brave.servlet.TracingFilter.doFilter(TracingFilter.java:82) at org.springframework.cloud.sleuth.instrument.web.LazyTracingFilter.doFilter(TraceWebServletAutoConfiguration.java:145) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:114) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:104) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:747) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.security.web.SecurityFilterChainPostProcessor$UaaLoggingFilter.doFilter(SecurityFilterChainPostProcessor.java:255) at org.cloudfoundry.identity.uaa.security.web.SecurityFilterChainPostProcessor$HttpsEnforcementFilter.doFilter(SecurityFilterChainPostProcessor.java:198) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.oauth.DisableIdTokenResponseTypeFilter.doFilterInternal(DisableIdTokenResponseTypeFilter.java:86) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at com.sas.logon.zone.IdentityZoneResolvingFilter.doFilterInternal(IdentityZoneResolvingFilter.java:77) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.web.LimitedModeUaaFilter.doFilterInternal(LimitedModeUaaFilter.java:85) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:97) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.authentication.UTF8ConversionFilter.validateParamsAndContinue(UTF8ConversionFilter.java:75) at org.cloudfoundry.identity.uaa.authentication.UTF8ConversionFilter.doFilter(UTF8ConversionFilter.java:59) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.web.HeaderFilter.doFilter(HeaderFilter.java:52) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.cloudfoundry.identity.uaa.metrics.UaaMetricsFilter.doFilterInternal(UaaMetricsFilter.java:87) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:151) at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:86) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
And I'm stuck with that error, guessing there is probably wrong with my LDAP tree architecture?
Thanks in advance for any help!
Problem solved by adding an empty group "sasusers".
Somehow the request failed when there was no group in the LDAP. Users don't even need to be in that group.
Closing that issue.
Problem solved by adding an empty group "sasusers".
Somehow the request failed when there was no group in the LDAP. Users don't even need to be in that group.
Closing that issue.
The SAS Users Group for Administrators (SUGA) is open to all SAS administrators and architects who install, update, manage or maintain a SAS deployment.
SAS technical trainer Erin Winters shows you how to explore assets, create new data discovery agents, schedule data discovery agents, and much more.
Find more tutorials on the SAS Users YouTube channel.