问题
I have two login sources (an Active Directory and a local MySQL Database) that each contain different users. I want to configure the Password flow in this way:
- query the AD first
- if this succeeds, the user gets logged in
- if it fails, query the local database and log the user in if this succeeds
- else, authentication fails
How can I achieve that?
回答1:
This is the solution I found:
inside the file conf/authn/password-authn-config.xml
put the following lines or replace if they already exist:
<import resource="jaas-authn-config.xml"/>
<!-- Ordered list of CredentialValidators to apply to a request. -->
<util:list id="shibboleth.authn.Password.Validators">
<ref bean="shibboleth.JAASValidator"/>
</util:list>
Comment out any other resources that you don't need, such as ldap-authn-config.xml
or krb5-authn-config.xml
.
In my case, I want the login to succeed if either of my login sources return 'okay'. Therefore you need this line:
<!-- Controls whether all validators in the above bean have to succeed, or just one. -->
<util:constant id="shibboleth.authn.Password.RequireAll" static-field="java.lang.Boolean.FALSE"/>
If you want all login sources to succeed, just replace 'FALSE' with 'TRUE'.
Next, put the following inside conf/authn/jaas-authn-config.xml
:
<!-- Specify your JAAS config. -->
<bean id="JAASConfig" class="org.springframework.core.io.FileSystemResource" c:path="%{idp.home}/conf/authn/jaas.config" />
<util:property-path id="shibboleth.authn.JAAS.JAASConfigURI" path="JAASConfig.URI" />
<!-- Specify the application name(s) in the JAAS config. -->
<util:list id="shibboleth.authn.JAAS.LoginConfigNames">
<value>ShibUserPassAuthLDAP</value>
<value>ShibUserPassAuthJAAS</value>
</util:list>
Now open conf/authn/jaas.config
and write this:
ShibUserPassAuthJAAS {
relationalLogin.DBLogin required debug=true
dbDriver="com.mysql.jdbc.Driver"
userTable="login"
userColumn="email"
passColumn="password"
dbURL="jdbc:mysql://localhost:3306/login"
dbUser="your_db_user"
dbPassword="your_db_password"
hashAlgorithm="SHA2" // or what u need
saltColumn="salt" // leave empty if you don't need this
errorMessage="Invalid password"
where="status < 9999"; // remove if you don't need this
};
ShibUserPassAuthLDAP {
org.ldaptive.jaas.LdapLoginModule required
ldapUrl="ldap://localhost:10389" // your active directory url
useStartTLS="true"
baseDn="OU=example,OU=example,DC=example,DC=org" // change this to whatever you need
bindDn="CN=shibboleth,OU=example,DC=example,DC=local" // change this to whatever you need
bindCredential="your_ad_password"
userFilter="(sAMAccountName={user})"
credentialConfig="{trustCertificates=file:/opt/shibboleth-idp/credentials/ldap.pem}";
};
relationalLogin.DBLogin
is a java class I use to actually check the credentials. You can download it from here: download the jar
Just put it in this directory on your idp: {shibboleth_root}/edit-webapp/WEB-INF/lib/
Now make sure you configured the password flow correctly in conf/authn/general_authn.xml
:
<bean id="authn/Password" parent="shibboleth.AuthenticationFlow"
p:passiveAuthenticationSupported="true"
p:forcedAuthenticationSupported="true"/>
And to enable the Password flow change this line in idp.properties
:
idp.authn.flows=
to this:
idp.authn.flows=Password
After you completed these steps, don't forget to restart jetty for the changes to take effect.
Explanation
The two entries called ShibUserPassAuthLDAP
and ShibUserPassAuthJAAS
in jaas-authn-config.xml
are where the magic happens: the password flow will try to validate the credentials using those two configurations you provided. It will try the first one and finish authentication if it succeeds, or try the second configuration if the first fails.
来源:https://stackoverflow.com/questions/65234929/shibboleth-4-idp-query-two-different-login-sources-with-the-password-flow