Startseite > Techblog > CoreMedia, JEE, Softwareentwicklung > CoreMedia und Spring Security verheiratet - Teil 1:...
mse

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.

uml

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.

Der AuthenticationManager 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"
  class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
  <property name="authenticationManager"><ref bean="authenticationManager"/></property>
  ...
</bean>
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
  <property name="providers">
    <list>
      <ref local="cmsDaoAuthenticationProvider" />
    </list>
  </property>
</bean>

<bean id="cmsDao" class="de.mse.authentication.CMUserDao"/>

<bean id="cmsDaoAuthenticationProvider"
  class="de.mse.authentication.CMAuthenticationProvider">
  <property name="userDetailsService">
    <ref bean="cmsDao"/>
  </property>
</bean>

Links

Kommentar Feed Trackback URL
Eine Antwort zu:
“CoreMedia und Spring Security verheiratet – Teil 1: Authentifizierung”

Hinterlassen Sie einen Kommentar

Tag Cloud

Unsere Themen

Kommentare

  • Niels Jaeckel: Hallo Ralf, wir haben heute das Benno auf die Version 1.1.3 aktualisiert. Dort funktioniert die...
  • Patrick: Super und Vielen Dank für diesen Artikel!! War genau das, was ich gesucht habe und hat mir sehr geholfen
  • hanjo: whileprintingrecords; {Gruppierfeld}=Previous({Grupp ierfeld}) Gruppierfeld natürlich. Bug im Editor, hat die...
  • hanjo: Bedingte Unterdrückung Detailbereich wie beschrieben. Bedingte Unterdrückung Gruppenkopf 1b:...
  • Niels Jaeckel: Hallo Ralf, wir haben es noch nicht mit dieser Benno-Version getestet. Allerdings steht das Update auf...

Twitter