I have integrated SAML 2.0 in my system and I have several questions about SAML configurations file.
In my Service Provider file I have
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>.
In the customer's IDP file we don't have any NameIDFormat definition.
What is de default NameIDFormat if the client didn't defined it?
In my spring saml configuration file
<bean id="samlEntryPoint" class="org.springframework.security.saml.SAMLEntryPoint">
<property name="contextProvider" ref="${saml.security.context.provider}" />
<property name="defaultProfileOptions">
<bean class="org.springframework.security.saml.websso.WebSSOProfileOptions">
<property name="includeScoping" value="false" />
<property name="nameID" value="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" />
<property name="allowCreate" value="true" />
</bean>
</property>
</bean>
But the client told us that the policy 'persitent' is not supported for him.
If I modify the defaultProfileOptions and I delete the nameID property, the default value for the client would be
urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified (I remember that in SP file the NameIDFormat is urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified and in IDP file we don't have the NameIDFormat definition)?
From SAML specification point of view NameID format
urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
should be used if no NameID format is specified. However you don't need to send anyone, the SAML IdP sould then choose one of your SP's supported NameID formats (provided in the SAML SP meta data).
From SAML spec point of view NameID format
urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
is intended to be used for the use case of 'account-linking' (linkage of 2 identities in 2 different identity silos, one on IdP side, on on SP side)
As your use-case seems to be SSO only, the intended NameID format would
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
Related
I'm getting the below error when using BCryptPasswordEncoder in CAS 4.2 (Central Authentication Service).:
java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder] to required type [org.jasig.cas.authentication.handler.PasswordEncoder] for property 'passwordEncoder': no matching editors or conversion strategy found
I've added all the dependencies in Maven. I also checked over CAS documents, but there is no proper information about how to configure BCryptPasswordEncoder with CAS.
deployerconfigcontext.xml (Maven for compilation):
<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:passwordEncoder-ref="passwordEncoder"
p:sql="select PASSWORD from SD_AD_DAT_LOGIN where ACCESS_NAME=?" />
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
I've connected CAS with the Oracle database, and it validated the plain text password correctly. Now I want to use bcrypt password encoding, and store the encode password in the database so that CAS should validate the encode password.
Help me understand the usage of BCryptPasswordEncoder with CAS.
After some more analysis i got to know that CAS 4.2.7 doesn't support Bcrypt encoding so to use this we need to write new custom class (BCryptSearchModeSearchDatabaseAuthenticationHandler) to handle bcrypt encoding.
deployerconfig.xml :
<bean id="primaryAuthenticationHandler"
class="io.wicket.cas.BCryptSearchModeSearchDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:tableUsers="SD_AD_DAT_LOGIN"
p:fieldUser="ACCESS_NAME"
p:fieldPassword="PASSWORD"
p:passwordEncoder-ref="passwordEncoder"/>
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#172.16.0.72:1521:xe" />
<property name="username" value="PROD17102018" />
<property name="password" value="PROD17102018" />
</bean>
I am using Spring SAML to implement single sign on in my application. Evreything is integrated and works properly from SSO perspective.
Another service of my application which also uses HTTP client post via Axis started failing with the following error
{http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLPeerUnverifiedException: SSL peer failed hostname validation for name: null
I have looked into the answer provided the link
Spring Security SAML + HTTPS to another page and follow the same but to no avail.
Below is the configuration for TLSProtocolSocketFactory
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="org.apache.commons.httpclient.protocol.Protocol"/>
<property name="targetMethod" value="registerProtocol"/>
<property name="arguments">
<list>
<value>https</value>
<bean class="org.apache.commons.httpclient.protocol.Protocol">
<constructor-arg value="https"/>
<constructor-arg>
<bean class="org.springframework.security.saml.trust.httpclient.TLSProtocolSocketFactory">
<constructor-arg ref="keyManager"/>
<constructor-arg><null/></constructor-arg>
<constructor-arg value="allowAll"/>
</bean>
</constructor-arg>
<constructor-arg value="443"/>
</bean>
</list>
</property>
</bean>
I have imported the cert of the other service in samlKeystore.jks as well.
Any help in the issue will be apreciated
I think this may be what you're looking for: Source
You are using bean TLSProtocolConfigurer which changes trusted certificates and hostname verification of the HTTPS protocol in the HTTP Client. You can revert behaviour of the HTTP Client back to defaults by removing this bean. You will then need to make sure that certificates used by entities from which you load metadata (https://idp.ssocircle.com/idp-meta.xml) are trusted in your cacerts, or use an endpoints without https (http://idp.ssocircle.com/idp-meta.xml).
Alternatively, you can disable hostname verification by setting property sslHostnameVerification to allowAll on bean TLSProtocolConfigurer. You will also need to make sure that the HTTPS certificate of https://www.somepage.com (or its CA) is included in the samlKeystore.jks (see Spring SAML manual).
You can find more details on the TLSProtocolConfigurer bean in the Spring SAML manual, chapter HTTP-based metadata provider with SSL.
The issue is in checkNames() function of PKIXX509CredentialTrustEngine where we are checking the trustedNames collection only for null instead of "null or Empty".Even though we are passing the value for trustedNames as null in TLSProtocolSocketFactory's getPKIXResolver() method to create StaticPKIXValidationInformatonResolver, the constructor of this class reinitialized the trustedNames collection to an empty collection.Changing the line from if(trustedNames == null) to if(trustedNames == null || trustedNames.isEmpty()) fixed the problem for me.
I'm authentication jasper server 5.6 to ldap active directory.ldapAuthenticationProvider bean configurations are ok.(userDnPatterns working).but server couldn't search in usersearch bean.this is my userSearch configuration.Am I correctly put values to constructor-arg ?
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0"><value>(sAMAccountName={0})</value></constructor-arg>
<constructor-arg index="1"><value>sAMAccountName={0},ou=IT Service Accounts</value></constructor-arg>
<constructor-arg index="2"><ref local="ldapContextSource"/></constructor-arg>
<property name="searchSubtree"><value>true</value></property>
</bean>
Thanks !
You should not use "sAMAccountName" as first parameter (index=0), as that parameter is the Directory search base.
If you want to use the default search base, leave the value blank.
Now, the second parameter, tells jasper (or any app that uses the FilterBasedLdapUserSearch method) how to search for the user, and what user should the app use to finally bind to the directory.
The fiter you specified on "index=1" would only work if AD has users DN's in the form:
DN: sAMAccountName=user,ou=IT Service Accounts, .....
Now, AD's default user DN's are more like: "CN=Full Name,CN=Users,....", so, in your case, you should be using only (sAMAccountName={0}) in the "FilterBasedLdapUserSearch" method, and then modify "LdapAuthenticationProvider" method to specify "userDnPatterns", like this:
<bean id="ldapAuthenticationProvider"
class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<constructor-arg><bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg><ref local="ldapContextSource"/></constructor-arg>
<property name="userDnPatterns"/>
<list> <value>CN={0},ou=IT Service Accounts</value> </list> </bean> </bean>
Of course, you should match this more closely to your setup, this is only an example.
I am using jasig cas4.0 server. I have implemented the Facebook oAuth2.0 support in my cas server and it works correctly. Now, I want to add Google oauth support (Google2Client) in the same CAS-server.
1) I created a new Project in console.developers.google.com, created a new client id under the OAuth with redirect uri to https://rajan.com:1443/cas/login (which actually points to localhost)
2) I added this to my applicationcontext.xml
<bean id="google1" class="org.pac4j.oauth.client.Google2Client">
<property name="key" value="<<CLIENT_ID>>" />
<property name="secret" value="<CLIENT_SECRET" />
<property name="scope" value="email" />
<property name="fields" value="id,name,first_name,middle_name,last_name,gender,email" />
</bean>
I also registered this bean in the clients
<bean id="clients" class="org.pac4j.core.client.Clients">
<property name="callbackUrl" value="https://rajan.com:1443/cas/login" />
<property name="clients">
<list>
<ref bean="facebook1" />
<ref bean="google1" />
</list>
</property>
</bean>
3) And finally, I added this in casLoginView.jsp
Authenticate with Facebook <br />
Authenticate with Google <br />
But, When I open the cas login view in the browser, the href for Google contains "https://rajan.com:1443/cas/login?service=https%3A%2F%2Frajan.com%3A2443%2FCasClientSimple%2F" instead of Google Oauth url. The facebook link works fine.
Could someone help me what I am missing here.
Thank you.
I checked the Google2OauthClient. There were no fields property.
So, just deleting the fields property in the above bean worked.
I also changed the field email with EMAIL_AND_PROFILE
I want my Spring application to try two pre-authentication methods (Siteminder and Java EE container authentication).
If either of these filters locates a username - I want to check that username against my database of users and assign roles based on what I see in the database. (I have an implementation of AuthenticationUserDetailsService, which does that for me.)
If not - show a login page to the user. Check the credentials they enter in the form against my database of users.
The Siteminder integration is working. The login form is working too. My problem is with the Java EE pre-authentication. It never kicks in.
My applicationContext-security.xml:
<!-- HTTP security configurations -->
<sec:http auto-config="true" use-expressions="true">
<sec:form-login login-processing-url="/resources/j_spring_security_check" always-use-default-target="true" default-target-url="/" login-page="/login"
authentication-failure-url="/login?login_error=t" />
<sec:logout logout-url="/resources/j_spring_security_logout" />
<sec:access-denied-handler error-page="/accessDenied" />
<sec:remember-me user-service-ref="customUserDetailsService" token-validity-seconds="86400" key="OptiVLM-VaultBalance" />
<sec:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter"/>
<sec:custom-filter after="PRE_AUTH_FILTER" ref="jeePreAuthenticatedFilter"/>
<!-- various intercept-url elements here, skipped for brevity -->
</sec:http>
<!-- Authentication Manager -->
<sec:authentication-manager alias="authenticationManager">
<!-- J2EE container pre-authentication or Siteminder -->
<sec:authentication-provider ref="customPreAuthenticatedAuthenticationProvider" />
<!-- Default provider -->
<sec:authentication-provider user-service-ref="customUserDetailsService" />
</sec:authentication-manager>
<!-- Siteminder pre-authentication -->
<bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="SM_USER" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="exceptionIfHeaderMissing" value="false" />
</bean>
<!-- J2EE pre-authentication -->
<bean id="jeePreAuthenticatedFilter" class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<!-- Custom pre-authentication provider -->
<bean id="customPreAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="customAuthenticationUserDetailsService" />
</bean>
I have Java 2 security enabled in Websphere, and I am logged in as 'admin5'. (I have a user with this username in my user database.) But when I access the application, there is never a call to the 'customAuthenticationUserDetailsService' bean to verify the username. I know this, because 'customAuthenticationUserDetailsService' does extensive logging which clearly shows what it is doing. When I am using the Siteminder pre-authentication - the 'customAuthenticationUserDetailsService' works just fine, I get some trace output in the log. But not for the J2EE authentication...
My guess is that one of these things is happening:
a) Java EE pre-authentication filter is not locating the username, so it never calls the authentication manager
b) Java EE pre-authentication filter works fine, but my custom authentication provider is never called by the authentication manager for some reason
By the way, the default authentication provider, which uses 'customUserDetailsService' does not kick in either. Again, I can tell that because there is no output from 'customUserDetailsService' in the log.
Can you advise on what could be the problem here? If not a solution, then a suggestion on how to approach this would be greatly appreciated.
OK, I figured this out. The problem is that even though I had J2EE security setup in Websphere and was authenticated, my web.xml contained no security constraints. Because of this, Websphere was not supplying the principal for my requests. This is apparently an intentional feature. If you are not accessing a protected URL, you should not need the pre-authentication information.
To overcome this, I added a security constraint to my web.xml, which allowed ALL users to access the resources. Effectively, the resources were not secured, but still - there was a constraint now.
This is it:
<security-constraint>
<web-resource-collection>
<web-resource-name>All areas</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
This tricks the Websphere into filling in the user principal information in the request.
Thank you #Ralph for his comments on this this question: request.getUserPrincipal() got null