CMS, CoreMedia, Hardware- und Softwareentwicklung, Java
Schreibe einen Kommentar

CoreMedia und Spring Security verheiratet – Teil 1: Authentifizierung

Erstellung eines CoreMedia-AuthenticationProviders für das Spring Security Framework

Einleitung und Funktionsweise

Neben dem Aufbau von geschlossenen Benutzergruppen (GBGs) im CMS kann es auch andere Gründe geben, das CoreMedia UserRepository für die Authentifizierung von Nutzern zu verwenden. Das Spring Security Framework (ehemals ACEGI Security) bietet Funktionalitäten für die Authentifizierung und Autorisierung von Nutzern. Im Folgenden Klassendiagramm sind die Interfaces und Klassen für die Authentifizierung dargestellt.

Standardmäßig sind im Framework bereits verschiedene Implementierungen vorhanden (z.B. für Datenbanken, LDAP u.a.). Mit wenig Aufwand kann man eigene Implementierungen wie die gegen das CoreMedia UserRepository implementieren.

DerAuthenticationManager ist der zentrale Einstieg für die Authentifizierung. Er kann mehrere verschiedene AuthenticationProvider verwalten. Über das Authentication-Objekt kann die Authentifizierung nur durch gewünschte Provider erfolgen (AuthenticationProvider#supports(Class authentication)).
Der UserDetailsService lädt das User-Objekt aus dem jeweiligen Repository per Namen (#loadUserByUsername(String username)). Der Provider überprüft das Passwort mit der Methode additionalAuthenticationChecks(...).

Implementierung

public class CMUserDao implements UserDetailsService{
...
public UserDetails loadUserByUsername(String username)
  throws UsernameNotFoundException, DataAccessException {
UserRepository userRepository = capConnection.getUserRepository();
org.acegisecurity.userdetails.User user = null;
try {
Repository repository = ContentRepositoryFactory.instance().getContentRepository();
User cmsUser = userRepository.getUserByName(username);
Collection < Group > groups = new ArrayList < Group >();
if (cmsUser != null) {
  groups = cmsUser.getGroups();
} else {
  throw new UsernameNotFoundException(username);
}
Collection < GrantedAuthority > authorities = new ArrayList < GrantedAuthority >();
if (groups != null) {
  for (Group group : groups) {
    authorities.add(new GrantedAuthorityImpl(group.getName()));
  }
}
user = new org.acegisecurity.userdetails.User(username, "", true, true, true, true,
  authorities.toArray(new GrantedAuthority[0]));
} catch (InvalidLoginException e) {
  throw new BadCredentialsException(e.getMessage(), e);
} catch (LicensesExceededException e) {
  new BadCredentialsException(e.getMessage(), e);
} catch (ConnectionNotOpenException e) {
  new BadCredentialsException(e.getMessage(), e);
}
return user;
}
...
}
public class CMAuthenticationProvider extends
    AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider {
...
protected void additionalAuthenticationChecks(UserDetails aUserDetails,
      UsernamePasswordAuthenticationToken aAuthenticationToken)
      throws AuthenticationException {

    String username = aUserDetails.getUsername();
    String password = aAuthenticationToken.getCredentials().toString();   

    boolean isValid = capConnection.isValidLogin(username, null, password);

    if (!isValid) {
      throw new BadCredentialsException(messages.getMessage(
          "AbstractUserDetailsAuthenticationProvider.badCredentials",
          "Bad credentials"), aUserDetails);
    }
  }
...
}

Benutzt man den AuthenticationProcessingFilter aus dem Framework wird nach erfolgreicher Authentifizierung das Authentication-Objekt in den SecurityContext geladen, einer ThreadLocal-Variable. Benutzt man einen eigenen Controller, muss man dies von Hand machen.

auth = authenticationManager.authenticate(...);
SecurityContextHolder.getContext().setAuthentication(auth);

Spring-Konfiguration

<bean id="authenticationProcessingFilter"
 >
  <property name="authenticationManager"><ref bean="authenticationManager"/></property>
  ...
</bean>
<bean id="authenticationManager">
  <property name="providers">
    <list>
      <ref local="cmsDaoAuthenticationProvider" />
    </list>
  </property>
</bean>

<bean id="cmsDao"/>

<bean id="cmsDaoAuthenticationProvider"
 >
  <property name="userDetailsService">
    <ref bean="cmsDao"/>
  </property>
</bean>

Links

Share on FacebookShare on Google+Tweet about this on TwitterPin on Pinterest

Schreib einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *