<?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>Triona Weblog</title>
	<atom:link href="http://blog.triona.de/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.triona.de</link>
	<description>Software Development and much more</description>
	<lastBuildDate>Sat, 04 Feb 2012 12:58:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Excel VBA Entwicklung (Teil 1): Makros</title>
		<link>http://blog.triona.de/development/excel-vba-development-part-1-macros.html</link>
		<comments>http://blog.triona.de/development/excel-vba-development-part-1-macros.html#comments</comments>
		<pubDate>Sat, 04 Feb 2012 12:57:38 +0000</pubDate>
		<dc:creator>Thomas Wehrspann</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[Makro]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1180</guid>
		<description><![CDATA[Alle kennen Excel, DAS Tabellenkalkulationsprogramm aus dem Hause Microsoft &#8211; aktuell in der Version 2010 erhältlich. Excel bietet eine Umfangreiche Bibliothek mit Funktionen unter anderem aus den Bereichen Mathematik, Finanz- und Ingenieurswesen. Es bietet Pivottabellen für Auswertungen und vielfältige Möglichkeiten der grafischen Aufbereitung mittels Diagrammen. Zudem liefert Excel mit der Skriptsprache Visual Basic for Applications, [...]]]></description>
			<content:encoded><![CDATA[<p>Alle kennen Excel, DAS Tabellenkalkulationsprogramm aus dem Hause Microsoft &#8211; aktuell in der Version 2010 erhältlich.</p>
<p>Excel bietet eine Umfangreiche Bibliothek mit Funktionen unter anderem aus den Bereichen Mathematik, Finanz- und Ingenieurswesen. Es bietet Pivottabellen für Auswertungen und vielfältige Möglichkeiten der grafischen Aufbereitung mittels Diagrammen. Zudem liefert Excel mit der Skriptsprache Visual Basic for Applications, kurz VBA, die Möglichkeit Makros aufzuzeichnen, um komplexe, sich wiederholende Aufgaben zu automatisieren. Steigt man tiefer in die Programmierung mit VBA ein, kann man eigenen Funktionen und Funktionsbibliotheken entwickeln, bis hin zu einer völlig eigenständigen (aberauf Excel basierenden) Anwendung. Die zur Programmierung nötige Entwicklungsumgebung, der Visual Basic Editor (VBE), liefert Excel gleich mit.</p>
<p>Ich will hier einen kurze Einstieg in die Entwicklung mit Excel VBA bieten.</p>
<h3>Makros</h3>
<p>Die für die meisten einfachste und schnellste Art ein VBA Programm zu schreiben dürfe sein es nicht selbst zu schreiben, sondern die Arbeit dem Makrorekorder zu überlassen.</p>
<p>Vor die Aufzeichnung des ersten Makros hat Excel allerdings die Optionen gesetzt. Die Makrofunktionen befinden sich im Ribbon im Register &#8220;Entwicklertools&#8221;. Dieses Register ist standardmäßig ausgeblendet und wird folgendermaßen sichtbar gemacht:</p>
<ol>
<li>Im Ribbon auf Register &#8220;<em>Datei</em>&#8221; gehen.</li>
<li>Den vorletzten Punkt &#8220;<em>Optionen</em>&#8221; aufrufen.</li>
<li>Im jetzt aufgegangenen Dialog auf der linken Seite &#8220;<em>Menüband anpassen</em>&#8221; wählen</li>
<li>und anschließend in der Liste &#8220;<em>Hauptregisterkarten</em>&#8221; einen Haken bei &#8220;<em>Entwicklertools</em>&#8221; setzen:</li>
</ol>
<p><a href="http://blog.triona.de/wp-content/uploads/2012/02/Blog_ExcelOptionsEntwicklertools.jpg"><img class="alignnone" src="http://blog.triona.de/wp-content/uploads/2012/02/Blog_ExcelOptionsEntwicklertools-300x219.jpg" alt="" width="300" height="219" /></a></p>
<p>Nun können wir auf das Register &#8220;Entwicklertools&#8221; gehen und finden dort im Abschnitts &#8220;Code&#8221; die Makrofunktionen:</p>
<p><a href="http://blog.triona.de/wp-content/uploads/2012/02/Blog_ExcelRibbonCodeMakros.jpg"><img class="alignnone size-full wp-image-1274" src="http://blog.triona.de/wp-content/uploads/2012/02/Blog_ExcelRibbonCodeMakros.jpg" alt="" width="192" height="110" /></a></p>
<p>&nbsp;</p>
<ul>
<li>&#8220;Makros&#8221;<br />
Hier erscheint ein Dialog mit dem man seine vorhandenen Makros verwalten und ausführen kann.<a href="http://blog.triona.de/wp-content/uploads/2012/02/Blog_ExcelMakro.jpg"><img class="alignnone size-thumbnail wp-image-1265" src="http://blog.triona.de/wp-content/uploads/2012/02/Blog_ExcelMakro-150x150.jpg" alt="" width="150" height="150" /></a></li>
<li>&#8220;Makro aufzeichnen&#8221; / &#8220;Aufzeichnung beenden&#8221;<br />
Mit dieser Funktion wird die Aufzeichnung eines Makros gestartet. Dabei werden alle ausgeführten Befehle in ihrer Reihenfolge zur späteren Wiedergabe aufgezeichnet. Auf diese Weise lassen sich komplexe und wiederkehrende Aufgaben automatisieren.<br />
<a href="http://blog.triona.de/wp-content/uploads/2012/02/Blog_ExcelMakroAufzeichnen.jpg"><img class="alignnone size-thumbnail wp-image-1266" src="http://blog.triona.de/wp-content/uploads/2012/02/Blog_ExcelMakroAufzeichnen-150x150.jpg" alt="" width="150" height="150" /></a></li>
<li>&#8220;Relative Aufzeichnung&#8221;<br />
Diese Option legt fest, ob beim Aufzeichnen der Makros die Zellpositionen absolut, oder relativ gespeichert werden sollen. Soll etwa die rechts von A1 liegende Zelle als B1 gespeichert werden, oder als &#8220;Rechts-von-der-aktuellen-Zelle&#8221;.</li>
<li>&#8220;Makrosicherheit&#8221;<br />
Diese Funktion ruft das Excel-Sicherheitscenter auf, wo man die Bedingungen zur Ausführung von Makros einstellen kann.</li>
</ul>
<p>Mit diesem Wissen kann jetzt jeder selbst Makros aufzeichnen:</p>
<ol>
<li>&#8220;Makro aufzeichnen&#8221;.</li>
<li>Name des Makros einstellen.</li>
<li>Arbeitsschritte in Excel abarbeiten.</li>
<li>&#8220;Aufzeichnung beenden&#8221;</li>
</ol>
<p>Über den Dialog &#8220;Makros&#8221; lässt sich das soeben aufgezeichnete Makro nun jederzeit starten und die aufgezeichneten Schnitte werden automatisch nacheinander ausgeführt.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/excel-vba-development-part-1-macros.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zeitgesteuerte Jobs in Java / JEE  (EJB-Timer und Quartz-Scheduler)</title>
		<link>http://blog.triona.de/development/java/zeitgesteuerte-jobs-in-java-jee-ejb-timer-und-quartz-scheduler.html</link>
		<comments>http://blog.triona.de/development/java/zeitgesteuerte-jobs-in-java-jee-ejb-timer-und-quartz-scheduler.html#comments</comments>
		<pubDate>Fri, 03 Feb 2012 13:06:47 +0000</pubDate>
		<dc:creator>Michael Graf</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1253</guid>
		<description><![CDATA[Problemstellung: Da wir für eines unserer Projekte zeitgesteuerte Prozesse benötigen und ich gerade am Architekturkonzept schreibe, habe ich verschiedene Technologien evaluiert. Dabei bin ich auf zwei verschiedene Frameworks gestoßen: EJB-Timer Quartz-Scheduler Die Anforderung ist: Zuverlässig in einem bestimmten Intervall (z.B. täglich um 23.30 Uhr oder an jedem Jahresende) eine Reihe von Prozessen auszuführen. Die Lösung [...]]]></description>
			<content:encoded><![CDATA[<h1>Problemstellung:</h1>
<p>Da wir für eines unserer Projekte zeitgesteuerte Prozesse benötigen und ich gerade am Architekturkonzept schreibe, habe ich verschiedene Technologien evaluiert. Dabei bin ich auf zwei verschiedene Frameworks gestoßen:</p>
<ul>
<li>EJB-Timer</li>
<li>Quartz-Scheduler</li>
</ul>
<p>Die Anforderung ist:</p>
<p>Zuverlässig in einem bestimmten Intervall (z.B. täglich um 23.30 Uhr oder an jedem Jahresende) eine Reihe von Prozessen auszuführen. Die Lösung muss mit Java 7 auf dem JBoss 7.0.2 deployed werden.</p>
<p>&nbsp;</p>
<h1>EJB-Timer:</h1>
<h2>Vorteil</h2>
<p>Um den EJB-Timer nutzen zu können müssen keine externen JAR-Dateien gesucht werden, da alles im javax.ejb-Packet enthalten ist. Die erforderliche JAR-Datei ist im JBoss integriert und im Eclipse-Projekt muss lediglich die JBoss 7.0 Runtime Bibliothek hinzugefügt werden.</p>
<h2>Nachteil</h2>
<p>Dafür musste ich leider feststellen, dass der „jboss-as-7.0.2.Final“ den &lt;Timer-Service&gt; nicht aktiviert hat. Um dies zu tun muss man die „Standalone-preview.xml“ laden. Dafür muss die standalone.bat (unter Windows) mit folgendem Parameter gestartet werden:</p>
<ul>
<li>standalone.bat -server-config=standalone-preview.xml</li>
</ul>
<p>Es darf dabei nicht vergessen werden, jegliche Änderung, die in der standalone.xml vorgenommen wurde, jetzt auch nochmal in der standalone-preview.xml einzutragen.</p>
<h2>Java-Code</h2>
<p>Um den Timer-Service zu nutzen, erstellt man eine EJB. Für die Problemstellung bietet sich ein @Singleton an, der per @Startup ausgeführt wird. Mit @Resource bekommt man den SessionContext, der wiederum über die Methode getTimerService() den gewünschten Service anspricht.</p>
<p>Um einen Timer zu erstellen, kennt der Service die Methode createTimer(Date startZeitpunkt, Long intervallInMillisekunden, Serializable nameDesTimers), mit der ein Timer initialisiert wird.</p>
<p>Nach jedem Intervall läuft der Timer in ein Timeout, für das die EJB eine Methode mit der Annotation @Timeout benötigt. Sie muss public void sein und als Übergabeparameter ein Timer-Objekt besitzen. Diese Methode wird bei jedem Timeout ausgeführt.</p>
<h2>Problem</h2>
<p>Beim ersten Ausprobieren war ich voller Euphorie als ich sah, dass in meinem eingestellten Intervall eine Nachricht auf der Konsole erschien. Als ich jedoch ein weiteres Mal deployed habe musste ich feststellen, dass der erste Timer immer noch lief, obwohl ich die War-Datei gelöscht, den JBoss beendet und wieder neu hochgefahren habe. Nach weiterer Recherche habe ich vom Timer-Service über die Methode getTimers() jeden aktiven Timer mit cancel() beendet. Trotzdem liefen mittlerweile sehr viele Timer weiter.</p>
<p>Scheinbar speichert der JBoss die seralisierten Timer-Objekte in irgendeinen Cache. Jedenfalls habe ich auch nach längerer Recherche nicht herausgefunden wie und wo die abgespeichert werden, bzw. wie ich sie wieder löschen kann. Falls jemand darüber Bescheid weiß, wäre es nett, wenn er mich kontaktieren würde.</p>
<p>&nbsp;</p>
<h1>Quartz-Scheduler</h1>
<h2>Vorteil</h2>
<p>Für den Quartz-Scheduler werden keine Änderungen in der JBoss-Konfiguration benötigt. Lediglich drei JAR-Dateien müssen dem Projekt beigefügt werden.</p>
<ul>
<li>Quartz-all-2.1.3.jar</li>
<li>Slf4j-api-1.6.1.jar</li>
<li>Slf4j-log4j12-1.6.1.jar</li>
</ul>
<p>Diese findet man auf der offiziellen Seite quartz-scheduler.org.</p>
<h2>Nachteil</h2>
<p>Um die JAR-Dateien herunter zu laden, muss man sich auf der Seite registrieren.</p>
<h2>Java-Code</h2>
<p>Um den Quartz-Scheduler zu nutzen, benötigt man drei Objekte. Einen Job der ausgeführt werden soll, einen Trigger, der sagt wann und in welchem Intervall der Job ausgeführt werden soll und einen Scheduler, in dem der Job einem Trigger zugewiesen und gestartet wird. Für die Implementierung bietet sich eine @Singleton @Startup EJB an, die beim initialisieren (@PostConstruct) die benötigten Objekte erstellt und den Scheduler startet.</p>
<h3>Job</h3>
<p>Man benötigt eine JavaKlasse, die das Interface org.quartz.Job implementiert und folgende Methode überschreibt:</p>
<ul>
<li>public void execute(JobExecutionContext context) throws JobExecutionException</li>
</ul>
<p>In dieser Methode kann beliebiger Java-Code stehen, der zeitgesteuert ausgeführt werden soll.</p>
<p>Dieser Job muss mit einem JobDetail-Objekt verbunden werden:<br />
<code><br />
JobDetailImpl jobHolidayTaken = new JobDetailImpl();<br />
jobHolidayTaken.setName("HolidayTakenJob");<br />
jobHolidayTaken.setJobClass(HolidayTakenJob.class);<br />
</code><br />
Der wird benötigt, da dem Scheduler ein Trigger zusammen mit einem JobDetail-Objekt übergeben wird.</p>
<h3>Trigger</h3>
<p>Der Trigger dient dazu, ein Intervall und einen Startzeitpunkt zu definieren, in dem ein Job ausgeführt werden soll. Es gibt verschiedene Arten von Triggern. Ich habe den SimpleTrigger und den CronTrigger versucht, wobei dem SimpleTrigger ein Startzeitpunkt und ein Intervall in Millisekunden übergeben werden. Der CronTrigger ist für unsere Problemstellung interessanter, da er über seine CronExpression-language mit dem Kalender klar kommt. Wenn man z.B. an jedem Monatsende einen bestimmten Prozess ausführen will, kommt man mit einem Millisekunden-intervall ohne zusätzliche Logik nicht aus. Die Syntax der CronExpression-language macht das zu einem Kinderspiel:</p>
<p><a href="http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger">http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger</a></p>
<p><strong>Beispiel:</strong><br />
<code><br />
Calendar startHolidayTaken = new GregorianCalendar();<br />
startHolidayTaken.set(2012, 1, 2, 16, 45, 0);<br />
CronTriggerImpl crontriggerHolidayTaken = new CronTriggerImpl();<br />
crontriggerHolidayTaken.setName("cronHolidayTaken");<br />
crontriggerHolidayTaken.setStartTime(startHolidayTaken.getTime());<br />
crontriggerHolidayTaken.setCronExpression("0 30 23 * * * *");<br />
</code><br />
Dieser Trigger wird täglich um 23:30 Uhr in ein Timeout laufen und den Job ausführen, den er im Scheduler zugewiesen bekommt.</p>
<h3>Scheduler</h3>
<p>Der Scheduler ist so etwas wie der Container, in dem sich die Trigger und die Jobs befinden. Der Scheduler verbindet einen Job mit einem Trigger und sorgt dafür, dass beim Timeout der Job ausgeführt wird.</p>
<p><strong>Beispiel:</strong><br />
<code><br />
this.scheduler = new StdSchedulerFactory().getScheduler();<br />
this.scheduler.start();<br />
this.scheduler.scheduleJob(jobHolidayTaken, crontriggerHolidayTaken);<br />
</code></p>
<h1>Fazit</h1>
<p>Ich habe die Evaluierung mit dem EJB-Timer angefangen, da wir sowieso einen EJB-Container in unserem JBoss haben und ich kein weiteres Framework einbinden wollte.</p>
<p>Da ich mich allerdings einen ganzen Tag mit dem EJB-Timer beschäftigt habe und zu keinem zufriedenstellenden Ergebnis gekommen bin (wie schon erwähnt: Ich würde mich über andere Erfahrungen darüber sehr freuen), habe ich mich für den Quartz-Scheduler entschieden, den ich innerhalb kurzer Einarbeitungszeit so zum Laufen bekommen habe, wie ich es brauchte.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/java/zeitgesteuerte-jobs-in-java-jee-ejb-timer-und-quartz-scheduler.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery &#8211; noConflict() und die Fallstricke</title>
		<link>http://blog.triona.de/development/jquery-noconflict-und-die-fallstricke.html</link>
		<comments>http://blog.triona.de/development/jquery-noconflict-und-die-fallstricke.html#comments</comments>
		<pubDate>Thu, 26 Jan 2012 00:35:27 +0000</pubDate>
		<dc:creator>Sebastian Adolph</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[alias]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[noConflict]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1230</guid>
		<description><![CDATA[jQuery hat sich in den vergangenen Jahren zu einer weit verbreiten JavaScript &#8211; Bibliothek entwickelt. Der Slogan dieser Bibliothek &#8220;Write less, do more&#8221; ist keine leere Versprechung. Ich habe nun in verschiedenen Projekten jQuery erfolgreich eingesetzt. In einem Projekt bin ich jedoch auf etwas gestossen, was unbekannt war für mich: Die Verwendung von unterschiedlichen Versionen [...]]]></description>
			<content:encoded><![CDATA[<p>jQuery hat sich in den vergangenen Jahren zu einer weit verbreiten JavaScript &#8211; Bibliothek entwickelt. Der Slogan dieser Bibliothek &#8220;Write less, do more&#8221; ist keine leere Versprechung. Ich habe nun in verschiedenen Projekten jQuery erfolgreich eingesetzt. In einem Projekt bin ich jedoch auf etwas gestossen, was unbekannt war für mich: Die Verwendung von unterschiedlichen Versionen von jQuery auf einer geladenen Seite.</p>
<p>Wie erreicht man das Zusammenspiel? Hierfür bietet jQuery die Funktion &#8220;noConflict()&#8221; an.</p>
<p>Ein paar Hintergrundinformationen: Hat man die jQuery &#8211; Bibliothek importiert auf seine Seite, sind die Funktionen von jQuery mittels &#8220;$&#8221; oder &#8220;jQuery&#8221; verfügbar; z.b. &#8216;jQuery(&#8220;div p&#8221;).hide();&#8217; oder &#8216;$(&#8220;div p&#8221;).hide();&#8217;</p>
<p>Verwenden nun andere Skript das &#8216;$&#8217; &#8211; Zeichen um die Funktionen verfügbar zu machen, so kann führt es dazu dass die Funktionen von anderen Bibliotheken nicht verfügbar sind, da jQuery bereits das &#8216;$&#8217; &#8211; Zeichen verwendet.</p>
<p>Was kann also getan werden?</p>
<p style="padding-left: 30px">1. jQuery.noConflict();<br />
2. jQuery(&#8220;div p&#8221;).hide();<br />
3. $(&#8220;content&#8221;).style.display = &#8216;none&#8217;;</p>
<p>Was wird in diesem Abschnitt getan?</p>
<p>1. Hier sagen wir: Gib dem anderen Skript den Alias &#8216;$&#8217; zurück; so dass &#8216;$&#8217; wieder für die andere Bibliothek zur Verfügung steht.<br />
2. Arbeite hier mit &#8220;jQuery&#8221; um jQuery &#8211; spezifische Funktion aufzurufen.<br />
3. Da wir in Zeile 1 &#8220;.noConflict()&#8221; aufgerufen haben, können wir hier mittels &#8216;$&#8217; die Funktionen einer anderen Bibliothek aufrufen.</p>
<p>Mittels &#8220;.noConflict()&#8221; kann auch die Verwendung von 2 unterschiedlichen jQuery &#8211; Versionen realisiert werden:</p>
<p style="padding-left: 30px">1. &lt;script src=&#8221;/domain/lib/js/jQuery1.3.2.js&#8221; type=&#8221;text/javascript&#8221;&gt;&lt;/script&gt;<br />
2. var jq = jQuery.noConflict();<br />
3. &lt;script src=&#8221;/domain/lib/js/jQuery1.5.1.js&#8221; type=&#8221;text/javascript&#8221;&gt;&lt;/script&gt;<br />
4. var player = jQuery.noConflict();</p>
<p>Was wird hier gemacht?</p>
<p style="padding-left: 30px">1. Importieren von einer jQuery &#8211; Bibliothek der Version 1.3.2.<br />
2. Setzen eines Aliasses &#8220;jq&#8221;, so dass alle Funktionalitäten von Version 1.3.2. unter dem Alias &#8220;jq&#8221; verfügbar sind.<br />
3. Importieren von einer jQuery &#8211; Bibliothek der Version 1.5.1.<br />
4. Setzen eines Aliasses &#8220;player&#8221;, so dass alle Funktionalitäten von Version 1.5.1. unter dem Alias &#8220;player&#8221; verfügbar sind.</p>
<p>So weit so gut. Doch welche Fallstrickt ergeben sich hieraus?</p>
<p>Es muss im Code darauf geachtet werden, das die beiden Aliasses konsequent verwendet werden!</p>
<p>Folgendes Beispiel demonstiert diesen Fallstrick:</p>
<p style="padding-left: 30px">function initEvents(id)<br />
{<br />
var _this = jQuery(this);<br />
var container = _this(id);</p>
<p style="padding-left: 30px">var viewSwitch = function(event, state){<br />
&#8230;<br />
}</p>
<p style="padding-left: 30px">viewContainer.bind(&#8220;viewSwitch&#8221;, viewSwitch);<br />
}</p>
<p style="padding-left: 30px">function init(id)<br />
{<br />
initEvents(id);<br />
}</p>
<p>In HTML &#8211; Seite steht folgendes:</p>
<p style="padding-left: 30px">jq(&#8220;body&#8221;).init(&#8220;list&#8221;));</p>
<p>Auf den ersten Blick sieht dieser Code fehlerfrei aus: Es wird eine Funktion aufgeruf, welche wiederum Events registriert (&#8220;bind&#8221;). Dies kann beim Starten der Zeit geschehen.</p>
<p>Das Problem liegt allerdings in der Zeile (<strong>&#8220;var _this = jQuery(this);&#8221;</strong>). Hier wird die aktive jQuery Bibliothek verwendet (unter dem Alias &#8220;jQuery&#8221; verfügbar).<br />
Dieses Event ist nun also unter &#8220;jQuery&#8221; registriert. Wird nun später eine andere jQuery &#8211; Version verwendet z.B. 1.5.1, so ist das vorher registrierte Event nicht mehr bekannt, da es unter jQuery 1.3.2. registriert wurde, nicht jedoch unter jQuery 1.5.1. Merke: jQuery zeigt auf die zuletzt importierte jQuery Bibliothek.</p>
<p>Um dies zu verdeutlichen:</p>
<p style="padding-left: 30px">1. Import von Version 1.3.2<br />
2. Setzen von Alias &#8220;jq&#8221; mittels &#8220;.noConflict()&#8221;.<br />
3. &#8220;jQuery&#8221; und Alias &#8220;jq&#8221; zeigen auf Version 1.3.2.<br />
4. Import von Version 1.5.2. &lt;- Hier entsteht das Problem.<br />
5. Setzen von Alias &#8220;jPlayer&#8221;<br />
6. &#8220;jQuery&#8221; und Alias &#8220;jPlayer&#8221; zeigen auf Version 1.5.1.</p>
<p>Die Lösung des Problems: In der Funktion &#8220;initEvents&#8221; muss statt &#8220;jQuery&#8221; das Alias &#8220;jq&#8221; verwendet werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/jquery-noconflict-und-die-fallstricke.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wo kommst das Event her?</title>
		<link>http://blog.triona.de/development/wo-kommst-das-event-her.html</link>
		<comments>http://blog.triona.de/development/wo-kommst-das-event-her.html#comments</comments>
		<pubDate>Wed, 25 Jan 2012 23:08:29 +0000</pubDate>
		<dc:creator>Sebastian Adolph</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Eventhandling]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Handling]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1225</guid>
		<description><![CDATA[Jeder kennt die Situation: Man entwickelt in Javascript, registriert u.a. viele Events etc. oder man arbeitet an einem bestehenden Projekt und muss das bestehenhe Javascript anpassen. Wie behält man in beiden Fällen den Überblick über die Events auf einer Seite? Ein Tool das ich im Rahmen einer Arbeit bei einem Kunden kennengelernt habe ist &#8220;visual [...]]]></description>
			<content:encoded><![CDATA[<p>Jeder kennt die Situation: Man entwickelt in Javascript, registriert u.a. viele Events etc. oder man arbeitet an einem bestehenden Projekt und muss das bestehenhe Javascript anpassen. Wie behält man in beiden Fällen den Überblick über die Events auf einer Seite?</p>
<p>Ein Tool das ich im Rahmen einer Arbeit bei einem Kunden kennengelernt habe ist &#8220;visual event&#8221;. Dieses Tool ist ein sogenanntes Bookmarklet.</p>
<p>Wie funktioniert es und was macht es? Man fügt per Drag&#8217;n'Drop von der Seite <a title="Visual Event Homepage" href="http://www.sprymedia.co.uk/article/Visual+Event" target="_blank">http://www.sprymedia.co.uk/article/Visual+Event </a>den Button &#8220;Visual Event&#8221; in die Bookmarkleiste des Browsers.</p>
<p>Danach geht man auf eine beliebige Seite deren Events man untersuchen möchte. Ist die Seite geöffnet, klick man auf das zuvor hinzugefügte Bookmark. Nach kurzer Zeit wird die Seite abgedunkelt und es erscheinen kleine, farbige Kästchen die über die Art des Events (Maus: Klick, Doppelklick, Mouseover; HTML &#8211; Events: select, blur, focus sowie UI Events: Key down, Key up etc.).</p>
<p>Fährt man mit der Maus über die Kästchen, erhält man Informationen wo im Skript diese Event behandelt wird.</p>
<p>Sehr hilfreich, wenn man den Überblick verliert, wer was wann wieso wo macht!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/wo-kommst-das-event-her.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enterprise Architect &#8211; XML-Schema generieren</title>
		<link>http://blog.triona.de/development/enterprise-architect-xml-schema-generieren.html</link>
		<comments>http://blog.triona.de/development/enterprise-architect-xml-schema-generieren.html#comments</comments>
		<pubDate>Fri, 23 Dec 2011 13:56:49 +0000</pubDate>
		<dc:creator>Danielle Berg</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[EA]]></category>
		<category><![CDATA[Enterprise Architect]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XML-Schema]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1208</guid>
		<description><![CDATA[Der Enterprise Architect (EA) bietet die Möglichkeit, aus einem bestehenden Klassenmodell ein XML-Schema zu erzeugen. Zu finden ist diese Funktion im Menü unter Project &#8211;&#62; XML Schema &#8211;&#62; Generate XML Schema Es erscheint ein Eingabedialog, in dem man Einstellung vornehmen kann, wie das XML-Schema generiert werden soll (z. B. Encoding) und unter welchem Pfad die [...]]]></description>
			<content:encoded><![CDATA[<p>Der <a href="http://www.sparxsystems.de/" target="_blank">Enterprise Architect (EA)</a> bietet die Möglichkeit, aus einem bestehenden Klassenmodell ein XML-Schema zu erzeugen.<br />
Zu finden ist diese Funktion im Menü unter <em>Project &#8211;&gt; XML Schema &#8211;&gt; Generate XML Schema</em></p>
<p><em><a href="../wp-content/uploads/2011/12/EA_generate_XML_schema_web.jpg"><img class="aligncenter  wp-image-1211" src="../wp-content/uploads/2011/12/EA_generate_XML_schema_web.jpg" alt="Enterprise Architect - Generate XML Schema" width="382" height="286" /></a></em></p>
<p>Es erscheint ein Eingabedialog, in dem man Einstellung vornehmen kann, wie das XML-Schema generiert werden soll (z. B. Encoding) und unter welchem Pfad die XSD-Datei abgelegt werden soll.<br />
Der Zielpfad für die XML-Schema-Datei lässt sich mit einem Doppelklick auf den Package Namen in der Tabelle <em>Package-Filename</em> ändern.</p>
<p><a href="http://blog.triona.de/wp-content/uploads/2011/12/EA_generate_XML_schema_detail_web1.jpg"><img src="http://blog.triona.de/wp-content/uploads/2011/12/EA_generate_XML_schema_detail_web1.jpg" alt="Enterprise Architect - Generate XML Schema Detail View" width="520" height="484" class="aligncenter size-full wp-image-1215" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/enterprise-architect-xml-schema-generieren.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Create Java Classes from XML-Schema</title>
		<link>http://blog.triona.de/development/java/create-java-classes-from-xml-schema.html</link>
		<comments>http://blog.triona.de/development/java/create-java-classes-from-xml-schema.html#comments</comments>
		<pubDate>Fri, 23 Dec 2011 12:53:58 +0000</pubDate>
		<dc:creator>Danielle Berg</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java Architecture for XML Binding]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[JDK]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XML-Schema]]></category>
		<category><![CDATA[XSD]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1192</guid>
		<description><![CDATA[JAXB (Java Architecture for XML Binding) is a framework to marshal Java objects to XML and vice-versa. It is part of the JDK and comes with a command-line compiler (xjc) that creates Java classes from an existing XML-Schema. Location The xjc it located at the /bin folder of the JDK: ../jdk1.6.0_18/bin/xjc.exe Usage xjc -d [target [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.oracle.com/technetwork/articles/javase/index-140168.html" title="JAXB" target="_blank">JAXB</a> (<a href="http://www.oracle.com/technetwork/articles/javase/index-140168.html" title="JAXB" target="_blank">Java Architecture for XML Binding</a>) is a framework to marshal Java objects to XML and vice-versa.<br />
It is part of the JDK and comes with a command-line compiler (<code>xjc</code>) that creates Java classes from an existing XML-Schema.</p>
<p><strong>Location</strong><br />
The xjc it located at the /bin folder of the JDK:<br />
<code>../jdk1.6.0_18/bin/xjc.exe</code></p>
<p><strong>Usage</strong><br />
xjc -d [target folder] -p [package name] [xml-schema file name]</p>
<p><strong>Example</strong><br />
The classes will be written to the folder &#8220;src&#8221; (relative to the current location) in the package &#8220;de.myproject.somepackage&#8221;.<br />
The schema file &#8220;my-schema.xsd&#8221; will be compiled.<br />
<code>xjc -d src -p de.myproject.somepackage my-schema.xsd</code></p>
<p>For more information see<br />
<code>xjc -help</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/java/create-java-classes-from-xml-schema.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CacheIgnoreHeaders Set-Cookie bei Apache mod_cache</title>
		<link>http://blog.triona.de/development/java/cacheignoreheaders-set-cookie-bei-apache-mod_cache.html</link>
		<comments>http://blog.triona.de/development/java/cacheignoreheaders-set-cookie-bei-apache-mod_cache.html#comments</comments>
		<pubDate>Thu, 03 Nov 2011 09:33:24 +0000</pubDate>
		<dc:creator>Joachim Schmidt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[CacheIgnoreHeaders]]></category>
		<category><![CDATA[Cookie]]></category>
		<category><![CDATA[JSESSIONID]]></category>
		<category><![CDATA[mod_cache]]></category>
		<category><![CDATA[Proxy]]></category>
		<category><![CDATA[Set-Cookie]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1178</guid>
		<description><![CDATA[&#8220;Kleine Ursache, große Wirkung&#8221; passt bei dieser Konfigurationseinstellung ziemlich genau. Ist sie nicht gesetzt, werden bei allen gecachten Seiten die eventuell vorhandenen &#8220;set-cookie&#8221; Parameter in den Headern mit in den Cache abgelegt. Das kann fatale Folgen haben, wenn z.B. eine JSESSIONID als Cookie gesetzt wird. Wird dann eine Seite mit dem &#8220;set-cookie&#8221; aus dem Cache [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Kleine Ursache, große Wirkung&#8221; passt bei dieser Konfigurationseinstellung ziemlich genau. Ist sie nicht gesetzt, werden bei allen gecachten Seiten die eventuell vorhandenen &#8220;set-cookie&#8221; Parameter in den Headern mit in den Cache abgelegt. Das kann fatale Folgen haben, wenn z.B. eine JSESSIONID als Cookie gesetzt wird. Wird dann eine Seite mit dem &#8220;set-cookie&#8221; aus dem Cache geladen, überschreibt diese JSESSIONID die aktuell vorhandene. Da die gecachte JSESSIONID aber einem ganz anderen Benutzer gehören könnte, ist es nun möglich, dessen Session zu übernehmen. Natürlich nur, falls dessen Session noch aktiv ist. Wenn nicht, dann gibt es zumindest einen ungewollten SessionTimedOut Fehler. Die Symptome treten allerdings auch nicht immer und nicht immer bei allen gecachten Inhalten auf, so dass der Fehler schwer reproduzierbar und auffindbar ist.</p>
<p>Apache mod_cache verursacht damit also ungewolltes &#8220;Session Hijacking&#8221;.</p>
<p>Abhilfe schafft das Setzen von &#8220;CacheIgnoreHeaders Set-Cookie&#8221;. Jeder, der mod_cache im Einsatz hat, sollte seine Konfiguration dahingehend prüfen wie diese Einstellung gesetzt ist und ob das so ausreichend ist.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/java/cacheignoreheaders-set-cookie-bei-apache-mod_cache.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monitoring Apache HTTP Server</title>
		<link>http://blog.triona.de/development/monitoring-apache-http-server.html</link>
		<comments>http://blog.triona.de/development/monitoring-apache-http-server.html#comments</comments>
		<pubDate>Fri, 21 Oct 2011 06:08:13 +0000</pubDate>
		<dc:creator>Danielle Berg</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[Apache HTTP]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Webserver]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1136</guid>
		<description><![CDATA[Für das Monitoring des Apache HTTP Servers stellt dieser eine Statusseite zur Verfügung: http://servername/server-status Voraussetzung ist, dass am Webserver das Modul mod_status aktiviert ist. Die Statusseite bietet folgende Informationen: Anzahl der arbeitenden Prozesse (requests currently being processed) Anzahl der Prozesse im Leerlauf (idle workers) Status jedes Prozesses (Zahl der abgearbeiteten Anfragen; Gesamtzahl der Bytes) Gesamtzahl [...]]]></description>
			<content:encoded><![CDATA[<p>Für das Monitoring des Apache HTTP Servers stellt dieser eine Statusseite zur Verfügung: http://servername/server-status<br />
Voraussetzung ist, dass am Webserver das Modul <a title="Apache HTTP Modul mod_status" href="http://httpd.apache.org/docs/2.2/mod/mod_status.html" target="_blank">mod_status</a> aktiviert ist.</p>
<p>Die Statusseite bietet folgende Informationen:</p>
<ul>
<li>Anzahl der arbeitenden Prozesse (requests currently being processed)</li>
<li>Anzahl der Prozesse im Leerlauf (idle workers)</li>
<li>Status jedes Prozesses (Zahl der abgearbeiteten Anfragen; Gesamtzahl der Bytes)</li>
<li>Gesamtzahl der Zugriffe und Bytes</li>
<li>Startzeit und Laufzeit des Servers</li>
<li>Durchschnittliche Anzahl der Anfragen je Sekunde, Bytes je Sekunde und durchschnittliche Zahl von Bytes je Anfrage</li>
<li>Aktueller CPU-Ressourcenverbrauch je Prozess und Apache insgesamt</li>
<li>Aktuell bearbeitete Hostnamen und Anfragen</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/monitoring-apache-http-server.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sicherheit in Java-EE6-Webapplikationen</title>
		<link>http://blog.triona.de/development/java/sicherheit-in-java-ee6-webapplikationen.html</link>
		<comments>http://blog.triona.de/development/java/sicherheit-in-java-ee6-webapplikationen.html#comments</comments>
		<pubDate>Tue, 18 Oct 2011 08:01:58 +0000</pubDate>
		<dc:creator>Bernhard Molz</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[auth constraint]]></category>
		<category><![CDATA[Java EE Sicherheit]]></category>
		<category><![CDATA[JDBC Realm]]></category>
		<category><![CDATA[JDBCRealm]]></category>
		<category><![CDATA[JNDIRealm]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[JSF login]]></category>
		<category><![CDATA[securing EJB]]></category>
		<category><![CDATA[securing JSF]]></category>
		<category><![CDATA[securing Servlets]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[security constraint]]></category>
		<category><![CDATA[Servlet 3.0 Login]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1012</guid>
		<description><![CDATA[Java-EE-Webapplikation absichern &#160; Authentifizierung und Autorisierung mit Servlet 3.0 und JDBCRealm &#160; In diesem Weblog möchte ich in aller Kürze das Thema &#8220;Anwendungssicherheit&#8221; in Java EE 6 erläutern. Als Applikationsserver habe ich Glassfish verwendet, Infos zum JBoss sind weiter unten verlinkt. Anhand eines Beispiels gehen wir die einzelnen Schritte durch, um den Server abzusichern und [...]]]></description>
			<content:encoded><![CDATA[<h1>Java-EE-Webapplikation absichern</h1>
<p>&nbsp;</p>
<h3>Authentifizierung und Autorisierung mit Servlet 3.0 und JDBCRealm</h3>
<p>&nbsp;</p>
<p>In diesem Weblog möchte ich in aller Kürze <img src='http://blog.triona.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  das Thema &#8220;Anwendungssicherheit&#8221; in<br />
Java EE 6 erläutern. Als Applikationsserver habe ich <strong>Glassfish</strong> verwendet,<br />
Infos zum <strong>JBoss</strong> sind weiter unten verlinkt.</p>
<p>Anhand eines Beispiels gehen wir die einzelnen Schritte durch, um den Server<br />
abzusichern und um unsere Web-Anwendung vor unberechtigtem Zugriff zu schützen.<br />
Die Web-Anwendung wird drei voneinander abgegrenzte Bereiche (admin, employee,<br />
manager) haben, die nur ein Nutzer mit der richtigen Rolle betreten darf.</p>
<p>&nbsp;</p>
<p>Ganz konkret werden wir an einer bestehenden Webapplikation folgende Dinge tun:</p>
<p>1. Wir sichern das <strong>Umfeld des Web-Servers</strong> ab. <a href="#kapitel1">[Link]</a></p>
<p>2. Wir erzeugen eine <strong>Datenbanktabelle</strong>, die User, Passwort und Rollen enthält. <a href="#kapitel2">[Link]</a></p>
<p>3. JSF Login: Wir bauen eine <strong>JSF-Login-Seite</strong>, die EJB nutzt, um Nutzer einzulassen oder<br />
auszusperren. Die Zugriffsberechtigungen liegen in einer SQL-Datenbank. <a href="#kapitel3">[Link]</a></p>
<p>4. <strong>Deployment Deskriptor web.xml</strong>: Wir setzen deklarativ SecurityConstraints in der<br />
web.xml, um Seiten vor unberechtigtem Zugriff zu schützen. <a href="#kapitel4">[Link]</a></p>
<p>5. <strong>EJBs und Servlets</strong>: Per Annotation setzen wir erlaubte und unerlaubte Rollen<br />
und können in EJBs sogar auf Methodenebene Nutzer ausschließen. <a href="#kapitel5">[Link]</a></p>
<p>&nbsp;</p>
<p>Unsere Web-Anwendung besteht aus folgenden Schichten:<br />
JSF 2.0 und Servlets 3.0 (z.B. Glassfish 3, JBoss 6+, Tomcat 7)<br />
EJB 3.1 (mind. JavaEE6)<br />
MySQL-Datenbank</p>
<p><a href="http://blog.triona.de/wp-content/uploads/2011/09/BlogDeployment1.png"><img class="alignnone size-full wp-image-1042" src="http://blog.triona.de/wp-content/uploads/2011/09/BlogDeployment1.png" alt="" width="216" height="427" /></a></p>
<p>&nbsp;</p>
<h2><a name="kapitel1" href="#kapitel1"></a>1. Server und Betriebssystem absichern</h2>
<p>Bevor wir uns daranmachen, unsere Web-Anwendung zu sichern, müssen wir erstmal<br />
daran, den Server und das Umfeld zu sichern. Wir legen hier die Basis für die Sicherheit<br />
unserer Web-Anwendung. Was hilft es, wenn unsere Web-Anwendung perfekt geschützt<br />
ist, aber der Server und das Betriebssystem angreifbar sind?</p>
<p>In diesem Artikel möchte ich nur einige Stichpunkte geben, da das Thema zu weitreichend<br />
ist, um es hier auch nur annähernd vollständig behandeln zu können.</p>
<p>1.1 Absichern des Betriebssystems:</p>
<ul>
<li>User mit eingeschränkten Rechten einrichten, nicht als Administrator auf dem BS arbeiten</li>
<li>Firewall, Virenscanner und gesunden Menschenverstand einschalten</li>
<li>&#8220;Sichere&#8221;, d.h. aktuelle und gepatchte Software verwenden</li>
<li>und vieles mehr</li>
</ul>
<p>1.2 Absichern des (Java Application) Servers:</p>
<ul>
<li>Nur Ports öffnen, die vom Server genutzt werden (s. %serverdir%/config/server.xml auf<br />
den meisten Java-Applikationsservern und Servlet-Containern)</li>
<li>Die Admin-Konsole per Passwort absichern. Hier einige Beispiele:<br />
<em>Tomcat (ungetestet)</em>: Die Datei <code>%tomcat%/conf/tomcat-users.xml</code> muss angepasst werden<br />
<em>Glassfish</em>: <code>%glassfish%/bin/asadmin change-master-password</code> bzw.<br />
<code>%glassfish%/bin/asadmin change-admin-password</code> auf der Kommandozeile ausführen<br />
<em>JBoss 7 (ungetestet)</em>:  <code>%jboss7%/standalone/configuration/mgmt-users.properties</code> editieren</li>
<li>und vieles mehr</li>
</ul>
<h2></h2>
<h2><a name="kapitel2" href="#kapitel2"></a>2. Authentifizierung mit einer Datenbanktabelle</h2>
<p>Für die Login-Seite müssen wir ein <strong>Realm</strong> anlegen.</p>
<p>Was ist ein Realm? Lt. Definition im offiziellen Tutorial von Sun ist ein Realm eine Sicherheits-<br />
domäne, die für einen Webserver definiert wird. Den Satz verstehe ich selber nur zur Hälfte,<br />
deshalb habe ich ein Bild gemalt, das diesen Sachverhalt klarer macht:</p>
<p><a href="http://blog.triona.de/wp-content/uploads/2011/09/Realm1.png"><img class="alignnone size-full wp-image-1047" src="http://blog.triona.de/wp-content/uploads/2011/09/Realm1.png" alt="" width="605" height="588" /></a></p>
<p>In Worten: Wir haben in der Datenbank einen User &#8216;holger&#8217;, der in der Gruppe &#8216;manager&#8217; ist,<br />
einen User &#8216;bernhard&#8217;, der in der Gruppe &#8216;employee&#8217; ist usw. Unsere Web-Anwendung definiert<br />
Rollen, die zufällig genauso heißen &#8211; aber auch anders heißen könnten. Nun müssen wir noch<br />
die in der Datenbank definierten Gruppen unserer Web-Anwendung bekannt machen: das<br />
geht über eine Mapping-Tabelle, die besagt, dass bspw. der Datenbankeintrag &#8216;manager&#8217; auf<br />
die Rolle &#8216;manager&#8217; unserer Web-Anwendung passt.</p>
<p>Ziel: Der &#8220;Manager&#8221; darf nur in den &#8220;Manager&#8221;-Bereich unserer Web-Anwendung und nur mit<br />
&#8220;manager&#8221; bezeichnete Geschäftslogik aufrufen, das Gleiche gilt für den Nutzer mit der Rolle<br />
&#8220;employee&#8221; und Nutzer der Rolle &#8220;admin&#8221;.</p>
<p>&nbsp;</p>
<p>So, jetzt müssen wir die User anlegen, die unsere Web-Anwendung im Login erkennen soll.<br />
Hier will ich die Erzeugung von Usern auf zwei Wegen behandeln &#8211; per FileRealm und per<br />
JDBCRealm. FileRealm ist einfacher, da wir dafür keine Datenbanktabelle und kein<br />
Mapping brauchen, aber wir können damit nicht dynamisch User anlegen, wie wir es mit<br />
dem datenbankbasierten JDBCRealm können, sondern müssen händisch User anlegen.</p>
<ul>
<li><strong>FileRealm</strong> (optional): wir legen die User mitsamt Gruppe per Hand auf dem Server (nicht per DB)<br />
an. Wenn nur der JDBC-Realm interessant ist, der überspringt diesen Abschnitt und<br />
klickt <a href="#jdbcrealm">hier</a>.<br />
Der Server legt dafür eine Datei auf dem Server an, die Username, gehashtes Passwort<br />
und Rollen enthält.<br />
Glassfish: In der Web-Oberfläche gehen wir auf den Punkt<br />
Konfigurationen -&gt; server-config -&gt;Sicherheit -&gt; Bereiche -&gt; file (s. Screenshot).<br />
<a href="http://blog.triona.de/wp-content/uploads/2011/09/filerealsuser.gif"><img class="alignnone size-medium wp-image-1049" src="http://blog.triona.de/wp-content/uploads/2011/09/filerealsuser-300x234.gif" alt="" width="300" height="234" /></a><br />
<a href="http://blog.triona.de/wp-content/uploads/2011/09/filerealm.gif"><img class="alignnone size-medium wp-image-1048" src="http://blog.triona.de/wp-content/uploads/2011/09/filerealm-300x258.gif" alt="" width="300" height="258" /></a><br />
Hier im Beispiel habe ich die User &#8216;fileBernhard&#8217; mit Gruppenzugehörigkeit &#8216;employee&#8217;<br />
angelegt, den &#8216;fileAdmin&#8217; mit Gruppe &#8216;admin&#8217; und &#8216;fileHolger&#8217; mit Gruppe &#8216;manager&#8217;.<br />
Wer das sofort mal testen will, kann den kommenden Abschnitt &#8216;JDBCRealm&#8217;<br />
überspringen und geht gleich zum Login unserer Web-Applikation <a title="Direkt zu Kapitel 3 &quot;JSF Login&quot; springen" href="#kapitel3">[Link]</a>.<strong><br />
JBoss</strong>: <a title="JBoss-Doku Realm" href="http://docs.jboss.org/jbossweb/3.0.x/realm-howto.html">http://docs.jboss.org/jbossweb/3.0.x/realm-howto.html</a> (ungetestet)</li>
<li><strong><a name="jdbcrealm" href="#jdbcrealm"></a>JDBCRealm</strong>: die Definition der User liegt in einer DB-Tabelle. Legen wir also eine<br />
DB-Tabelle an:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`myuser`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`id`</span> <span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`username`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">30</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`password`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">30</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`group`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">30</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>und legen ein paar Datensätze an:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">`myuser`</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #ff0000;">`username`</span> <span style="color: #66cc66;">,</span> <span style="color: #ff0000;">`password`</span> <span style="color: #66cc66;">,</span> <span style="color: #ff0000;">`group`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">VALUES</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'admin'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'adminpw'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'admin'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'bernhard'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'bernhardpw'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'employee'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'holger'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'holgerpw'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'manager'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'karlheinz'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'karlheinzpw'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'employee'</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Ok, wir haben jetzt 4 Datensätze. Die müssen wir jetzt unserer Web-Anwendung bekannt<br />
machen (s. Abb. &#8220;Realm&#8221;).</p>
<p>Nächster Schritt: Im Glassfish müssen wir die Datei WEB-INF/glassfish-web.xml anlegen, die<br />
unsere &#8220;Gruppen&#8221; in unserer Datenbank-Tabelle auf die &#8220;Rollen&#8221; auf dem Server überträgt.</p>
<p><strong>glassfish-web.xml</strong></p>
<pre>  &lt;security-role-mapping&gt;
    &lt;role-name&gt;admin&lt;/role-name&gt;
    &lt;group-name&gt;admin&lt;/group-name&gt;
  &lt;/security-role-mapping&gt;
  &lt;security-role-mapping&gt;
    &lt;role-name&gt;employee&lt;/role-name&gt;
    &lt;group-name&gt;employee&lt;/group-name&gt;
  &lt;/security-role-mapping&gt;
  &lt;security-role-mapping&gt;
    &lt;role-name&gt;manager&lt;/role-name&gt;
    &lt;group-name&gt;manager&lt;/group-name&gt;
&lt;/security-role-mapping&gt;</pre>
<p>Im JBoss gibt es ebenfalls die Security Roles mit leicht unterschiedlicher Notation:<br />
<a href="http://docs.jboss.org/jbosssecurity/docs/6.0/security_guide/html/J2EE_Declarative_Security_Overview.html#J2EE_Declarative_Security_Overview-Security_roles">JBoss-Docs zum Mapping</a></p>
<p>Wir müssen die Datenbank dem Server über JNDI bekannt machen: wie das geht, hat<br />
Kollege Joachim beschrieben: <a title="Globale JNDI-Resourcen" href="http://blog.triona.de/development/java/globale-jndi-resourcen-in-tomcat.html">[Link zu JNDI]</a></p>
<p>Jetzt legen wir das JDBCRealm an:<br />
bei Glassfish geht das über die Weboberfläche,<br />
bei JBoss über die Konfigurationsdatei <code>$CATALINA_HOME/conf/server.xml <a title="JBoss-Docs zu JDBCRealm" href="http://blog.triona.de/development/java/jax-ws-webservice-endpoint-url-zur-laufzeit-andern.html">[Link]</a></code><br />
<a title="Link zu JBoss-Docs zu JDBCRealm" href="http://docs.jboss.org/jbossweb/3.0.x/realm-howto.html#JDBCRealm">JBoss-Docs zu JDBCRealm</a></p>
<p><a href="http://blog.triona.de/wp-content/uploads/2011/09/jdbcrealm.gif"><img src="http://blog.triona.de/wp-content/uploads/2011/09/jdbcrealm-300x217.gif" alt="" width="300" height="217" /></a></li>
</ul>
<p>&nbsp;</p>
<h2><a name="kapitel3" href="#kapitel3"></a>3. JSF Login-Seite</h2>
<p>Wir nähern uns langsam dem ersten Erfolg. Erstellen wir also die Login-Seite als JSF-Facelet:<br />
<strong>login.xhtml</strong></p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

&lt;html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:h="http://java.sun.com/jsf/html"&gt;
	&lt;head&gt;
		&lt;title&gt;Login&lt;/title&gt;
	&lt;/head&gt;
	&lt;h:body&gt;
		&lt;h:form id="j_security_check"&gt;
			&lt;center&gt;
				&lt;h:messages errorClass="errorMessage" infoClass="infoMessage"
							warnClass="warnMessage"&gt;&lt;/h:messages&gt;
				&lt;h:panelGrid columns="2"&gt;
					&lt;h:outputText value="Username : "/&gt;
					&lt;h:inputText id="j_username" value="#{loginBean.username}"/&gt;

					&lt;h:outputText value="Password : "/&gt;
					&lt;h:inputSecret id="j_password" value="#{loginBean.password}"/&gt;

					&lt;h:commandButton value="Submit" action="#{loginBean.login}"
									 type="submit"/&gt;
				&lt;/h:panelGrid&gt;
			&lt;/center&gt;
		&lt;/h:form&gt;
	&lt;/h:body&gt;
&lt;/html&gt;</pre>
<p>Und die <strong>logout.xhtml</strong>:</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

&lt;html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:h="http://java.sun.com/jsf/html"&gt;

	&lt;head&gt;
		&lt;title&gt;&lt;/title&gt;
	&lt;/head&gt;
	&lt;h:body styleClass="body"&gt;
		&lt;h:messages&gt;&lt;/h:messages&gt;
		&lt;h:form&gt;
			&lt;h:commandLink value="Logout" action="#{loginBean.logout}"&gt;&lt;/h:commandLink&gt;
		&lt;/h:form&gt;
	&lt;/h:body&gt;
&lt;/html&gt;</pre>
<p>Wir man sieht, greift das Facelet auf eine <code>loginBean</code> zu.<br />
Diese wollen wir jetzt definieren:<br />
<strong>LoginBean.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">de.triona.ejb</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.Serializable</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.security.Principal</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.logging.Logger</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.faces.application.FacesMessage</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.faces.bean.ManagedBean</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.faces.context.FacesContext</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.servlet.ServletException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.servlet.http.HttpServletRequest</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.servlet.http.HttpSession</span><span style="color: #339933;">;</span>
&nbsp;
@ManagedBean
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LoginBean <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> username<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> password<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> login<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		FacesContext fc <span style="color: #339933;">=</span> FacesContext.<span style="color: #006633;">getCurrentInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		HttpServletRequest request <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>HttpServletRequest<span style="color: #009900;">&#41;</span> fc.<span style="color: #006633;">getExternalContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">//Login per Servlet 3.0</span>
			request.<span style="color: #006633;">login</span><span style="color: #009900;">&#40;</span>username, password<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// Der Principal entspricht dem Usernamen</span>
			<span style="color: #003399;">Principal</span> principal <span style="color: #339933;">=</span> request.<span style="color: #006633;">getUserPrincipal</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// Wir können hier nur abfragen, ob der User eine Rolle hat (isUserInRole('whatever')),</span>
			<span style="color: #666666; font-style: italic;">// aber wir können NICHT die Rolle aktiv erfragen (z.B. mit getUserRole(...))</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>request.<span style="color: #006633;">isUserInRole</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;admin&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #003399;">String</span> msg <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;User: &quot;</span> <span style="color: #339933;">+</span> principal.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;, Role: admin&quot;</span><span style="color: #339933;">;</span>
				fc.<span style="color: #006633;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #000000; font-weight: bold;">new</span> FacesMessage<span style="color: #009900;">&#40;</span>FacesMessage.<span style="color: #006633;">SEVERITY_INFO</span>, msg, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;admin/startrek&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>request.<span style="color: #006633;">isUserInRole</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;manager&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #003399;">String</span> msg <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;User: &quot;</span> <span style="color: #339933;">+</span> principal.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;, Role: manager&quot;</span><span style="color: #339933;">;</span>
				fc.<span style="color: #006633;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #000000; font-weight: bold;">new</span> FacesMessage<span style="color: #009900;">&#40;</span>FacesMessage.<span style="color: #006633;">SEVERITY_INFO</span>, msg, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;manager/timesheet&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>request.<span style="color: #006633;">isUserInRole</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;employee&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #003399;">String</span> msg <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;User: &quot;</span> <span style="color: #339933;">+</span> principal.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;, Role: employee&quot;</span><span style="color: #339933;">;</span>
				fc.<span style="color: #006633;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #000000; font-weight: bold;">new</span> FacesMessage<span style="color: #009900;">&#40;</span>FacesMessage.<span style="color: #006633;">SEVERITY_INFO</span>, msg, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;employee/work&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;du_musst_die_rollen_noch_definieren&quot;</span><span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">// hier sollte etwas sinnvolles passieren ;-)</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>ServletException e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			fc.<span style="color: #006633;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #000000; font-weight: bold;">new</span> FacesMessage<span style="color: #009900;">&#40;</span>FacesMessage.<span style="color: #006633;">SEVERITY_ERROR</span>, <span style="color: #0000ff;">&quot;An Error Occured: Login failed&quot;</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;loginFailed&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> logout<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		FacesContext fc <span style="color: #339933;">=</span> FacesContext.<span style="color: #006633;">getCurrentInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		HttpSession session <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>HttpSession<span style="color: #009900;">&#41;</span> fc.<span style="color: #006633;">getExternalContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>session <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			session.<span style="color: #006633;">invalidate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		fc.<span style="color: #006633;">getApplication</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getNavigationHandler</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">handleNavigation</span><span style="color: #009900;">&#40;</span>fc, <span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #0000ff;">&quot;/login.xhtml&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getUsername<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> username<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setUsername<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> username<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">username</span> <span style="color: #339933;">=</span> username<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getPassword<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> password<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setPassword<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> password<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">password</span> <span style="color: #339933;">=</span> password<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Die Besonderheit an diesem Code ist die Methode <code>HttpServletRequest.login(username,password)</code><br />
<code></code>aus der Servlet-Spezifikation 3.0 und <code>HttpServletRequest.isUserInRole(String role)</code>.<br />
Mit <code></code><code>login(username,password)</code>  wird username und password des Realms (hier: JDBCRealm oder<br />
FileRealm) validiert. Die Methode <code>HttpServletRequest.isUserInRole(String role)</code> ist selbst-<br />
erklärend: hier wird die Rolle abgefragt, wir können aber aus Sicherheitsgründen nicht &#8211; und das ist<br />
Absicht der Java EE 6 Spezifikation &#8211; aktiv die Rolle abfragen.</p>
<p>&nbsp;</p>
<p><strong>Zwischenstand: </strong></p>
<ul>
<li>wir haben eine <strong>DB-Tabelle myusers</strong> (mit Name, Passwort und Gruppe) angelegt und befüllt</li>
<li><span style="color: #999999">wir haben einen <strong>FileRealm</strong> auf dem Server angelegt (dieser Schritt ist optional)</span></li>
<li>wir haben einen <strong>JDBCRealm</strong> angelegt</li>
<li>wir haben eine JSF-Seite <strong>login.xhtml</strong> angelegt, die auf die <strong>EJB-Klasse LoginBean</strong> zugreift</li>
<li>wir haben auf dem Glassfish die XML-Datei glassfish-web.xml bzw. auf dem JBoss die SecurityRoles<br />
angelegt, die das Datenbankfeld myuser.group auf die Rollen in der Web-Applikation abbildet</li>
</ul>
<p><strong>Was fehlt noch?</strong></p>
<p>&nbsp;</p>
<h2><a name="kapitel4" href="#kapitel4"></a>4. web.xml bearbeiten</h2>
<p>Wir müssen unserem Deployment-Deskriptor (WEB-INF/)web.xml mitteilen, das er eine Authentifizierung<br />
anhand unseres Formulars login.xhtml durchführt und wir müssen unsere Rollen definieren.<br />
In der Netbeans-Oberfläche können wir die web.xml grafisch bearbeiten.<br />
<a href="http://blog.triona.de/wp-content/uploads/2011/09/webxmlLoginRoles.gif"><img class="alignnone size-medium wp-image-1065" src="http://blog.triona.de/wp-content/uploads/2011/09/webxmlLoginRoles-300x181.gif" alt="" width="300" height="181" /></a></p>
<p>Wer direkt die web.xml bearbeiten will, kann das auch tun:<br />
<strong>web.xml</strong></p>
<pre>    &lt;login-config&gt;
        &lt;auth-method&gt;FORM&lt;/auth-method&gt;
        &lt;realm-name&gt;loginRealm&lt;/realm-name&gt;
        &lt;form-login-config&gt;
            &lt;form-login-page&gt;/login.xhtml&lt;/form-login-page&gt;
            &lt;form-error-page&gt;/loginfailed.xhtml&lt;/form-error-page&gt;
        &lt;/form-login-config&gt;
    &lt;/login-config&gt;
    &lt;security-role&gt;
        &lt;description/&gt;
        &lt;role-name&gt;manager&lt;/role-name&gt;
    &lt;/security-role&gt;
    &lt;security-role&gt;
        &lt;description/&gt;
        &lt;role-name&gt;admin&lt;/role-name&gt;
    &lt;/security-role&gt;
    &lt;security-role&gt;
        &lt;description/&gt;
        &lt;role-name&gt;employee&lt;/role-name&gt;
    &lt;/security-role&gt;</pre>
<p>Probieren wir das Ganze aus: wir starten die login.xhtml im Browser.<br />
Loggen wir uns erfolgreich als admin ein, dann sollten wir zur Seite /admin/startrek.xhtml<br />
weitergeleitet werden, der manager wird auf /manager/timesheet.xhtml und der employee auf<br />
/employee/work.xhtml weitergeleitet.</p>
<p>So weit, so gut: wir können uns einloggen und unsere Rolle ist dem Server bekannt.<br />
Ein Problem haben wir noch: wer zufällig den Link für den Admin-Bereich kennt, kann<br />
diese Seiten aufrufen, dito für den Employee- und den Manager-Bereich.</p>
<p>Das können wir so ebenfalls in der web.xml fixen, indem wir URLs explizit für eine Rolle<br />
erlauben. Der Admin darf nur URLs mit dem Pattern /admin/* aufrufen, dito für employee<br />
und Manager:<br />
Hier via Netbeans:<br />
<a href="http://blog.triona.de/wp-content/uploads/2011/09/webxmlConstraints.gif"><img class="alignnone size-medium wp-image-1066" src="http://blog.triona.de/wp-content/uploads/2011/09/webxmlConstraints-204x300.gif" alt="" width="204" height="300" /></a><br />
Und hier der XML-Codeausschnitt aus der <strong>web.xml</strong>:</p>
<pre>    &lt;security-constraint&gt;
        &lt;display-name&gt;AdminConstraint&lt;/display-name&gt;
        &lt;web-resource-collection&gt;
            &lt;web-resource-name&gt;AdminArea&lt;/web-resource-name&gt;
            &lt;description/&gt;
            &lt;url-pattern&gt;/admin/*&lt;/url-pattern&gt;
        &lt;/web-resource-collection&gt;
        &lt;auth-constraint&gt;
            &lt;description/&gt;
            &lt;role-name&gt;admin&lt;/role-name&gt;
        &lt;/auth-constraint&gt;
        &lt;user-data-constraint&gt;
            &lt;description/&gt;
            &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
        &lt;/user-data-constraint&gt;
    &lt;/security-constraint&gt;
    &lt;security-constraint&gt;
        &lt;display-name&gt;EmployeeConstraint&lt;/display-name&gt;
        &lt;web-resource-collection&gt;
            &lt;web-resource-name&gt;EmployeeArea&lt;/web-resource-name&gt;
            &lt;description/&gt;
            &lt;url-pattern&gt;/employee/*&lt;/url-pattern&gt;
        &lt;/web-resource-collection&gt;
        &lt;auth-constraint&gt;
            &lt;description/&gt;
            &lt;role-name&gt;employee&lt;/role-name&gt;
        &lt;/auth-constraint&gt;
    &lt;/security-constraint&gt;
    &lt;security-constraint&gt;
        &lt;display-name&gt;ManagerConstraint&lt;/display-name&gt;
        &lt;web-resource-collection&gt;
            &lt;web-resource-name&gt;ManagerArea&lt;/web-resource-name&gt;
            &lt;description/&gt;
            &lt;url-pattern&gt;/manager/*&lt;/url-pattern&gt;
        &lt;/web-resource-collection&gt;
        &lt;auth-constraint&gt;
            &lt;description/&gt;
            &lt;role-name&gt;manager&lt;/role-name&gt;
        &lt;/auth-constraint&gt;
    &lt;/security-constraint&gt;</pre>
<p>In diesem Beispiel habe ich den Admin-Bereich via SSL-geschützt</p>
<pre>&lt;user-data-constraint&gt;&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;&lt;/user-data-constraint&gt;</pre>
<p>Der Browser leitet direkt von http auf https um.</p>
<p>Langsam geht es auf das Finale zu:</p>
<p>&nbsp;</p>
<h2><a name="kapitel5" href="#kapitel5"></a>5. Annotationsbasierter Schutz von Servlets und EJBs</h2>
<p>Wir haben das Schlimmste hinter uns. Jetzt folgt die Kür und die wunderbare Welt<br />
der Annotationen.</p>
<p>Fangen wir mit dem Servlet an. Wir wollen ein Servlet schreiben, das nur User mit den Rollen<br />
<code>manager</code> und <code>admin</code> besuchen können. Nichts leichter als das:</p>
<p><strong>ManagerAndAdminServlet.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@ServletSecurity<span style="color: #009900;">&#40;</span>@HttpConstraint<span style="color: #009900;">&#40;</span>rolesAllowed<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;manager&quot;</span>, <span style="color: #0000ff;">&quot;admin&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ManagerAndAdminServlet <span style="color: #000000; font-weight: bold;">extends</span> HttpServlet <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1046L<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> processRequest<span style="color: #009900;">&#40;</span>HttpServletRequest request, HttpServletResponse response<span style="color: #009900;">&#41;</span>
			<span style="color: #000000; font-weight: bold;">throws</span> ServletException, <span style="color: #003399;">IOException</span> <span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">//manager und admin dürfen rein, der employee bleibt draußen mit einer SecurityException</span>
        <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Mit der Annotation</p>
<pre>@ServletSecurity(@HttpConstraint(rolesAllowed={"manager", "admin"}))</pre>
<p>ist schon alles fertig.</p>
<p>&nbsp;</p>
<p>Genauso einfach ist eine EJB vor unautorisiertem Zugriff geschützt:</p>
<p><strong>WorkBean.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@DeclareRoles<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;manager&quot;</span>, <span style="color: #0000ff;">&quot;employee&quot;</span>, <span style="color: #0000ff;">&quot;admin&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
@Stateless
@LocalBean
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> WorkBean <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/** Nur für Nutzer mit Rolle 'employee' */</span>
	@RolesAllowed<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;employee&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doWork<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> employee<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;work&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/** Nur für Nutzer mit Rolle 'manager' */</span>
	@RolesAllowed<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;manager&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> delegateWork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;delegateWork&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/** Nur für den 'admin' */</span>
	@RolesAllowed<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;admin&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> administrateWhatever<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;administrateWhatever&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/** Alle Nutzer ('manager', 'employee' und 'admin') dürfen diese Methode aufrufen */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> lookOutOfTheWindow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;it rains&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>&nbsp;</p>
<p>Unser Web-Anwendung könnte bspw. jetzt so aussehen:</p>
<p><a href="http://blog.triona.de/wp-content/uploads/2011/09/project_outline1.gif"><img class="alignnone size-full wp-image-1071" src="http://blog.triona.de/wp-content/uploads/2011/09/project_outline1.gif" alt="" width="255" height="430" /></a><br />
Fazit: Wir haben unsere Web-Anwendung deklarativ und programmativ schützen können.<br />
Natürlich haben wir zum Thema Anwendungssicherheit nur die Spitze des Eisbergs gesehen.<br />
Dies ist nur ein erster Einblick.</p>
<p>Liebe Leser, vielen Dank für eure Aufmerksamkeit.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/development/java/sicherheit-in-java-ee6-webapplikationen.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Pencil Project &#8211; A Prototyping tool</title>
		<link>http://blog.triona.de/general/the-pencil-project-a-prototyping-tool.html</link>
		<comments>http://blog.triona.de/general/the-pencil-project-a-prototyping-tool.html#comments</comments>
		<pubDate>Sun, 09 Oct 2011 20:44:57 +0000</pubDate>
		<dc:creator>Sebastian Adolph</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[diagram]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Prototyping]]></category>
		<category><![CDATA[sketching]]></category>

		<guid isPermaLink="false">http://blog.triona.de/?p=1103</guid>
		<description><![CDATA[Have you ever been in the situation to develop a User Interface? With the help of &#8220;Pencil&#8221; you can do this quite easily! This project has the following main features: Stencils for diagraming and prototyping Multiple pages per project Linking between each page Text editing including rich &#8211; text editing Exporting to HTMl, PNG, Office [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever been in the situation to develop a User Interface? With the help of &#8220;Pencil&#8221; you can do this quite easily!</p>
<p>This project has the following main features:</p>
<ul>
<li>Stencils for diagraming and prototyping</li>
<li>Multiple pages per project</li>
<li>Linking between each page</li>
<li>Text editing including rich &#8211; text editing</li>
<li>Exporting to HTMl, PNG, Office documents (Open Office &amp; Word), PDF</li>
<li>Supports Undo/redo</li>
<li>Installing user-defined stencils and templates</li>
<li>Aligning to a grid, z-ordering, scaling, rotating etc.</li>
<li>Cross-platforms</li>
<li>Clipart Browser</li>
<li>Object snapping</li>
</ul>
<p>The Pencil Project has two versions: Desktop version and a Firefox &#8211; Plugin. I have made the experience that the desktop version is faster then the Firefox &#8211; Plugin. Another advantage of the desktop version is the that its independet. Imagine you update your browser and the Pencil projects hasnt updated yet. There are of course portable versions of the Firefox. But its a point to consider!</p>
<p>The project is published under the GPLv2 license. It works under GNU/Linux 2.6 (Fedora, Ubuntu and Arch) with GTK+, Windows XP and Windows Vista/7.</p>
<p>The application can be downloaded  <a href="http://pencil.evolus.vn/en-US/Home.aspx" target="_blank">http://pencil.evolus.vn/en-US/Home.aspx</a>.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.triona.de/general/the-pencil-project-a-prototyping-tool.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

