Im folgenden finden Sie unsere endgültige Umsetzung im Projekt. Grundlegender Fluss ist:
a) Überprüfen Sie die Benutzer-ID und die Rollen während der Authentifizierung. Wenn der Benutzer nicht definiert ist oder keine Rollen für die Anwendung hat, authentifizieren Sie den Benutzer nicht.
b) Wenn Benutzer die Datenbankprüfung bestehen, fahren Sie mit der LDAP-Authentifizierung fort.
c) Zusammenführen der Rollen aus der Datenbank mit ldap, die während der Anwendung verwendet werden sollen.
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter implements InitializingBean {
...
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(this.ldapAndDatabaseAuthenticationProvider());
}
@Bean(name="ldapAuthenticationProvider")
public AuthenticationProvider ldapAndDatabaseAuthenticationProvider(){
LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper();
userDetailsMapper.setRoleAttributes(new String[]{"groupMembership"});
LdapAndDatabaseAuthenticationProvider provider =
new LdapAndDatabaseAuthenticationProvider(this.ldapAuthenticator(), this.ldapAuthoritiesPopulator());
provider.setUserDetailsContextMapper(userDetailsMapper);
return provider;
}
@Bean(name = "ldapAuthoritiesPopulator")
public LdapAndDatabaseAuthoritiesPopulator ldapAuthoritiesPopulator(){
return new LdapAndDatabaseAuthoritiesPopulator(this.contextSource(), "");
}
@Bean(name = "ldapAuthenticator")
public LdapAuthenticator ldapAuthenticator() {
BindAuthenticator authenticator = new BindAuthenticator( this.contextSource());
authenticator.setUserDnPatterns(new String[]{"cn={0},ou=prod,o=COMP"});
return authenticator;
}
@Bean(name = "contextSource")
public DefaultSpringSecurityContextSource contextSource() {
DefaultSpringSecurityContextSource contextSource =
new DefaultSpringSecurityContextSource(ldapUrl);
return contextSource;
}
Hier ist, wie weitere Rollen populator (LdapAndDatabaseAuthoritiesPopulator) umgesetzt.
public class LdapAndDatabaseAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator{
public LdapAndDatabaseAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase) {
super(contextSource, groupSearchBase);
}
protected Set<GrantedAuthority> getAdditionalRoles(DirContextOperations user,
String username) {
Set<GrantedAuthority> mappedAuthorities = new HashSet<GrantedAuthority>();
/* Add additional roles from other sources for this user*/
/* below add is just an example of how to add a role */
mappedAuthorities.add(
new GrantedAuthority() {
private static final long serialVersionUID = 3618700057662135367L;
@Override
public String getAuthority() {
return "ROLE_MYAPP_USER"; //this is just a temporary role we are adding as example. get the roles from database.
}
@Override
public String toString(){
return this.getAuthority();
}
});
for (GrantedAuthority granted : mappedAuthorities) {
log.debug("Authority : {}", granted.getAuthority().toString());
}
return mappedAuthorities;
}
}
Unten ist, wie die benutzerdefinierte LDAP-Authentifizierungsanbieter (LdapAndDatabaseAuthenticationProvider) implementiert Benutzer zu überprüfen, ob haben Rollen in der Datenbank definiert ist erforderlich, um auf die Anwendung zugreifen. Wenn der Benutzer nicht in der Datenbank ist oder Rollen fehlen, wird die Authentifizierung das Konto DisabledException auslösen.
franDays auch vorgeschlagen, "Custom Authentication Provider" zu verwenden. Ich möchte ihm einen Kredit geben.
public class LdapAndDatabaseAuthenticationProvider extends LdapAuthenticationProvider{
public LdapAndDatabaseAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) {
super(authenticator, authoritiesPopulator);
}
@Override
protected DirContextOperations doAuthentication(
UsernamePasswordAuthenticationToken authentication) {
log.debug("Checking if user <{}> is defined at database to use this application.", authentication.getName());
// Here is the part we need to check in the database if user has required role to log into the application.
// After check if user has the role, do nothing, otherwise throw exception like below example.
boolean canUserAuthenticate = isActiveUserExist(authentication.getName());
log.debug("canUserAuthenticate: {}", canUserAuthenticate);
if (!canUserAuthenticate)
throw new DisabledException("User does not have access to Application!");
return super.doAuthentication(authentication);
}
private boolean isActiveUserExist(String userId) {
// Do your logic here are return boolean value...
}
In meiner Anwendung habe ich Rollen und Rollen Privilegien.In diesem Fall was ich zuweisen sollte in der Methode mappedAuthorities. (Rollenname oder Privilegname) –