<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>code mitte</title>
	<atom:link href="http://www.code-mitte.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.code-mitte.de</link>
	<description></description>
	<lastBuildDate>Wed, 22 Feb 2012 10:40:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Session Support for the Play Framework</title>
		<link>http://www.code-mitte.de/blog/session-support-for-the-play-framework/</link>
		<comments>http://www.code-mitte.de/blog/session-support-for-the-play-framework/#comments</comments>
		<pubDate>Wed, 15 Feb 2012 09:57:57 +0000</pubDate>
		<dc:creator>Moritz Thielcke</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[Play]]></category>

		<guid isPermaLink="false">http://www.code-mitte.de/?p=591</guid>
		<description><![CDATA[Am Anfang dieses kleinen Tutorials sollte ich erwähnen, dass Sessions bei den meisten Play-Projekten nicht unbedingt nötig sind. Play basiert auf einem &#8220;Share-Nothing&#8221;-Prinzip und ist darauf ausgelegt, auf mehreren Server-Instanzen parallel laufen zu können. Durch die integrierte Memcache-Implementierung und dem &#8230; <a href="http://www.code-mitte.de/blog/session-support-for-the-play-framework/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div>Am Anfang dieses kleinen Tutorials sollte ich erwähnen, dass Sessions bei den meisten Play-Projekten nicht unbedingt nötig sind. Play basiert auf einem &#8220;Share-Nothing&#8221;-Prinzip und ist darauf ausgelegt, auf mehreren Server-Instanzen parallel laufen zu können. Durch die integrierte Memcache-Implementierung und dem auf Cookies basierenden Security-Modul sind die meisten Projekte auch ohne Session-Objekte problemlos umsetzbar.<br />Bei Webseiten, die auf intensive Benutzerinteraktion abzielen,  kann ein Session-Object aber durchaus von Nutzen sein. Ausserdem finde ich es nicht besonders elegant, den Benutzernamen in einem Cookie als Plaintext abzuspeichern, wie es das Play Security-Modul macht. Auch wenn der Cookie signiert ist, präferiere ich eine Identifikation über eine Session-ID.<br />Ziel dieses Tutorials ist es daher, eine serverseitige Sessionverwaltung zu implementieren. Dafür nutzen wir die von Play gelieferte Cache Funktionalität. Dadurch wird die Session, je nach Konfiguration, entweder im Speicher der Anwendung verwaltet, oder über einen externen Memcache.<br />Falls Ihr Projekt später auf mehren Instanzen laufen soll, sollten Sie auf eine hybride Session-Verwaltung von Memcache und Datenbank setzen, um einen Single Point of Failure zu vermeiden.   </div>
<div><span id="more-591"></span></div>
<div><strong><strong> ( <a href="http://dormando.livejournal.com/495593.html">http://dormando.livejournal.com/495593.html</a> )</strong></strong></p>
<p>&nbsp;</p>
</div>
<div>
<p><strong><strong><span style="font-size: large;">Example: User Session<br /></span><br /></strong></strong>Das folgende Beispiel benötigt ein Play Projekt mit konfiguriertem Security-Modul. Des Weiteren nutzte ich ein Model “User” mit den Feldern “Username” und “Password”.            </p>
<div>( <a href="http://pastebin.com/35vwkB3Q">http://pastebin.com/35vwkB3</a> )<br /> </div>
<div>Um unsere Session zu implementieren, erweitern wir das Security-Modul. Dadurch können wir auf schon vorhandene Funkionalitäten zugreifen. Dafür erzeugen wir im Package &#8220;controller&#8221; eine neue Java-Klasse, zB. &#8220;SessionImpl.java&#8221;:<strong><strong><br /></strong></strong></div>
<div>
<div>
<pre class="wp-code-highlight prettyprint linenums:1">public class SessionImpl extends Secure.Security{
  private static Map scache;
}</pre>
</div>
<p dir="ltr">Da es sich bei der Secure.Security-Klasse um ein Controller handelt, besitzt jeder Request seine eigene statische Map (“scache”).</p>
<p dir="ltr">Nun machen wir uns an die authenticate() Funktion. Diese wird später aufgerufen, wenn sich ein User über das Security-Modul einloggt:</p>
<div>
<pre class="wp-code-highlight prettyprint linenums:1">    static boolean authenticate(String username, String password) {
      User user = null;
      if(&quot;admin&quot;.equals(username) &amp;amp;&amp;amp;  &quot;admin&quot;.equals(password)){
           //for testing purpose
           user = new User(username, password);
      }
      else{
          user = User.login(username, password);
     }
       if(user != null)
         scache = new HashMap();
         scache.put(&quot;user&quot;,user);
         scache.put(&quot;sessionID&quot;, session.getId());
         Cache.set(&quot;session_&quot;+session.getId(), scache, &quot;30mn&quot;);//30 mins session timeout
         Logger.debug(&quot;user &quot;+user+&quot; logged in as session &quot;+session.getId());
         return true;
     }      
      return false;
}
</pre>
</div>
</div>
<div>
<p dir="ltr">Als nächstes implementieren wir eine Funktion,  die vor Aufruf eines annotierten Controllers überprüft, ob sich der Benutzer eingeloggt hat:</p>
</div>
<div>
<pre class="wp-code-highlight prettyprint linenums:1">   @Before(unless={&quot;login&quot;, &quot;authenticate&quot;, &quot;logout&quot;})
   static void checkUser() throws Throwable{
      Logger.debug(&quot;connected session: &quot;+session.getId());
     try{
          scache = (Map) Cache.get(&quot;session_&quot;+session.getId());
      }catch(ClassCastException ex){
         Logger.error(&quot;cant load session &quot;, ex);
      }
     User u = getUser();
      if( u == null )
           Secure.login();   
      else
           Logger.debug(&quot;Logged in as &quot;+u);
  }

   public static User getUser(){
       if(scache!=null &amp;amp;&amp;amp;  scache.get(&quot;user&quot;) != null){
          return (User) scache.get(&quot;user&quot;);
      }
     return null;
  }</pre>
</div>
<div>Damit Änderungen am Session-Objekt auch im Cache landen, benötigen wir zusätzlich noch eine Funktion, die nach Aufruf des annotierten Controllers die Session speichert:</div>
<div>
<div>
<pre class="wp-code-highlight prettyprint linenums:1">   @After
   static void syncSession(){
       Logger.debug(&quot;saving session to cache&quot;);
       if(scache!=null)
           Cache.set(&quot;session_&quot;+session.getId(), scache, &quot;30mn&quot;);
   }</pre>
</div>
<div>Als Letztes noch eine Getter-Funktion für das Session-Objekt, um den Zugriff von Controllern zu gewährleisten:</div>
<div>
<pre class="wp-code-highlight prettyprint linenums:1">  static Map getCache(){
     return scache;
   }</pre>
</div>
<div><strong id="internal-source-marker_0.3961390322074294">Die komplette Klasse gibt es unter: <a href="http://pastebin.com/BqLz0CqU">http://pastebin.com/BqLz0CqU</a>.<br /> </strong></div>
<div>
<div>Mit der fertigen Implementierung können wir nun Controller-Klassen mit @With annotieren, um sie ausschließlich für eingeloggte User zur Verfügung zu stellen:</div>
</div>
<div>
<pre class="wp-code-highlight prettyprint linenums:1">@With(SessionImpl.class)
public class Application extends Controller {
  public static void index() {
       User user = SessionImpl.getUser();
       render(user);
  }
}</pre>
</div>
<div>
<p dir="ltr">Wollen wir unsere Implementierung noch um Gruppenrichtlinien erweitern, können wir das mit Hilfe der @Check(“profile”)-Annotation umsetzen:</p>
<div>
<pre class="wp-code-highlight prettyprint linenums:1">public class SessionImpl extends Secure.Security {
       //..
   static boolean check(String profile) {   
      User u = getUser();
     if(u != null &amp;amp;&amp;amp; u.hasProfile(profile)) {
               return true;
     }

     return false;
  }</pre>
</div>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.code-mitte.de/blog/session-support-for-the-play-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

