Studien-Projektarbeit mit Grails

Das Informatik-Studium beinhaltet in der Hochschule Karlsruhe auch praktische Übungen. In der Regel bemühen sich Anfang Oktober eine Vielzahl von junger (meist) hoch motivierter Informatik-Studenten um möglichst einen passendes Projekt für das 5te Semester zu bekommen.
Das Gedränge kann durchaus groß sein, da hierbei die goldene Regel gilt: „wer zuerst kommt, malt zuerst“. Zudem ist der Begriff ‘passend’ auf den jeweiligen Studenten gemünzt. Manche Studenten suchen nach einem für Ihn möglichst interessanten Thema, manche wollen von ihrem meist-geschätzten Professor betreut werden und wiederum andere wollen lieber eine ruhige Kugel schieben. Soweit so gut, nun gibt es allerdings noch eine Alternative zu den aufgeführten Möglichkeiten an eine Projektarbeit zu kommen. Der Student überlegt sich ein Thema und spricht einen Professor an, ob dieser das ausgewählte Thema betreuen möchte.
Da ich zu Beginn des Semesters noch nichts von der letzten Möglichkeit gewusst hatte und ich ansonsten wenig begeistert von den angebotenen Themen war, musste ich mir etwas einfallen lassen. Nach einem aufschlussreichen Gespräch in der Fachschaft, wusste ich nun auch von der Möglichkeit ein Projekt direkt mit einem Professor auszuhandeln.
Da ich die „neue“ Welt der dynamischen Sprachen im Java-Umfeld schon immer sehr reizvoll gefunden hatte legte ich mich auf das Schreiben einer einfachen Webapplikation mit dem Grails-Framework fest. Die Überlegung dahinter war recht einfach, es musste neu und spannend sein (ansonsten würde der betreuende Professor das Projekt abweisen) und ich hatte schon länger eine Projektidee, die durch das Studium nun vorangetrieben wurde. Nun ist es aber bekanntermaßen so, dass bei einer Studienarbeit der Anteil der Dokumentation und Planung recht hoch sein kann. Dementsprechend wählte ich auch keine brandneue Technologie. Die Dokumentation und die erhältlichen Tutorials würden den Einsteig sicherlich stark vereinfachen.
Es stellt sich nun die Frage wie ich überhaupt zum Thema Grails bekommen bin. Die Antwort ist ziemlich simpel – Mundpropaganda. Ich kann mich noch gut an einen Abend in der Kneipe erinnern. Ich saß mit befreundeten ehemaligen Arbeitskollegen bei einem kühlen Bier und wir debattierten wie so des öfteren über die Webentwicklung mit Grails. “Wir können zu dritt in einem Monat das Projekt an dem wir nun schon jahrelang mit einem vollen Entwicklerteam schrauben nachbauen“. Mit diesem Satz im Hinterkopf ist mein Studienprojekt entstanden.
Das sollte genug  zur Vorgeschichte des Studien-Projekts sein,. In einem kleinen Tutorial zum das Grails Spring-Security -Plugins möchte das Plugin-System von Grails demonstrieren:
Meine Umgebung:

  • Ubuntu 12.04
  • Eclipse IDE (Groovy/Grails Tool Suite von SpringSource)
  • Grails 2.1.0
  • Java 1.6.0_24

Um das Grails-Plugin nutzen zu können, ist es nötig das hierzu benötigte Plugin zu installieren. Es gibt 2 Möglichkeiten dies zu bewerkstelligen:
Über die Komandozeile:

grails install-plugin spring-security-core

oder über einen Eintrag in der grails-app/conf/BuildConfig.groovy:

plugins {
    compile ":spring-security-core:1.2.7.1"
}

Da ich die Übersicht der BuildConfig inzwischen zu schätzen weiß, wählte ich die zweite Variante.
Zur Überprüfung/Installation des Plugins muss nun der Befehl

grails compile

ausgeführt werden. Dieser Befehl löst die eingetragene Plugin-Dependency auf.
Der nächste Schritt nutzt nun gleich ein Skript des installierten Plugin für die Erstellung der nötigen Domain-Klassen.

grails s2-quickstart <meinePackageStruktur> User Role

Diese 3 kleinen Befehle reichen für die Grundfunktionalität von SpringSecurity aus.
Zur Überprüfung der Login-Funktionalität macht es Sinn in der grails-app/conf/Bootstrap.groovy ein paar Testdaten einzufügen:

class BootStrap{
  def init={servletContext->
    RoleuserRole=Role.findByAuthority('ROLE_USER')?:newRole(authority:'ROLE_USER').save(failOnError:true)
    Role adminRole=Role.findByAuthority('ROLE_ADMIN')?:newRole(authority:'ROLE_ADMIN').save(failOnError:true)
    UseradminUser=User.findByUsername('adminUser')?:newUser(username:'adminUser',enabled:true,password:'topSecret').save(failOnError:true)
    if(!adminUser .authorities.contains(userRole))
       UserRole.create(adminUser,userRole,true)
    if(!adminUser .authorities.contains(adminRole))
       UserRole.create(adminUser,adminRole,true)
    User dummyUser=User.findByUsername('dummyUser')?:newUser(username:'dummyUser',enabled:true,password:'notSoSecret').save(failOnError:true)
    if(!dummyUser.authorities.contains(userRole))
       UserRole.create(dummyUser,userRole,true)
    ...
  }
  assertUser.count()==2
  assertRole.count()==2
  assertUserRole.count()==3
  …
}

Nun kann man beliebige Teile seiner Applikation von SpringSecurity überwachen lassen.
Ob auf Klassenebene/Methodenebene kann einfach per Annotation gesteuert werden.

import org.springframework.dao.DataIntegrityViolationException
import grails.plugins.springsecurity.Secured
@Secured(['ROLE_USER'])
class MyFancyController {
...
@Secured(['ROLE_ADMIN'])
def mySuperfancyAdminOnlyMethod(){
...
}

Ein kurzer Funktionstest auf der Weboberfläche überzeugt von der Funktionalität.

Über den Controller:

 localhost:<myPort>/<myApp>/dbconsole

lässt sich die Struktur von der Datenhaltung in SpringSecurity leicht nachvollziehen.
Um noch mehr Funktionalität und auch generierte Admin-Oberflächen zu bekommen, ist es möglich das spring-security-ui plugin zu installieren. Dies stellt eine AJAX fähige Oberfläche zum Login bereit, sowie eine ganzen Haufen von Admin-Funktionalität. Weiterhin gibt es zusätzlich noch einige weitere Plugins rund um das Thema Spring-Security:

  • Spring Security ACL which adds support for object-level and method-level authorization using ACLs (access control list)
  • Spring Security AppInfo which provides a basic UI to view the security configuration
  • Spring Security CAS which adds support for single sign-on using Jasig CAS
  • Spring Security OpenID which adds support for OpenID authentication
  • Spring Security Facebook which adds support for Facebook authentication
  • Spring Security Kerberos which adds support for single sign-on using Kerberos
  • Spring Security LDAP which adds support for LDAP and ActiveDirectory authentication
  • Spring Security Mock which adds support for fake/mock authentication during developement
  • Spring Security RADIUS which adds support for RADIUS authentication
  • Spring Security Shibboleth Native SP which adds support for container provided Shibboleth authentication.
  • Spring Security Twitter which adds support for Twitter authentication

Dies sollte einen kleine Überblick über den Aufbau und die Installation eines Grails-Plugins im Allgemeinen und von springSecurity im speziellen geben können.