<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Mike&#039;s Notes</title>
	<atom:link href="http://mrdwnotes.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mrdwnotes.wordpress.com</link>
	<description>Power, knowledge, wise guy</description>
	<lastBuildDate>Sat, 06 Oct 2012 17:26:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='mrdwnotes.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Mike&#039;s Notes</title>
		<link>http://mrdwnotes.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://mrdwnotes.wordpress.com/osd.xml" title="Mike&#039;s Notes" />
	<atom:link rel='hub' href='http://mrdwnotes.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Twitter Login to a Java Web Application</title>
		<link>http://mrdwnotes.wordpress.com/2011/11/29/twitter-login-to-a-java-web-application/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/11/29/twitter-login-to-a-java-web-application/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 23:35:47 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mrdwnotes.wordpress.com/?p=170</guid>
		<description><![CDATA[Having taken  Bruce Phillips Shiro tutorial&#8217;s app and added a login via Facebook option I&#8217;m now going to have a bash at implementing a &#8220;log in via twitter&#8221; option, I then will hopefully be able to step back and see what generlisations might be appropriate to make some of the code more generic between Facebook [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=170&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Having taken  <a title="http://www.brucephillips.name/blog/index.cfm/2009/4/5/An-Introduction-to-Ki-formerly-JSecurity--A-Beginners--Tutorial-Part-2" href="http://www.brucephillips.name/blog/index.cfm/2009/4/5/An-Introduction-to-Ki-formerly-JSecurity--A-Beginners--Tutorial-Part-2">Bruce Phillips Shiro tutorial&#8217;s app</a> and added a <a title="http://mrdwnotes.wordpress.com/2011/11/28/using-apache-shiro-security-to-allow-login-via-facebook-part-1/" href="http://mrdwnotes.wordpress.com/2011/11/28/using-apache-shiro-security-to-allow-login-via-facebook-part-1/">login via Facebook </a>option I&#8217;m now going to have a bash at implementing a &#8220;log in via twitter&#8221; option, I then will hopefully be able to step back and see what generlisations might be appropriate to make some of the code more generic between Facebook and Twitter logins, and also genererally for OAuth.</p>
<h2>So first Create a Twitter Application</h2>
<p>Do this on dev.twitter.com ,  with an application name, description and website.</p>
<p>There&#8217;s also an optional field for a call back URL, I&#8217;ve filled this in with the URL of the servlet that will be handling twitter login&#8217;s for my application, although twitter does say &#8221; OAuth 1.0a applications should explicitly specify their <tt>oauth_callback</tt> URL on the request token step, regardless of the value given here&#8221;. So I may have to revisit this to determine which URL exactly should be entered.</p>
<p>This gives a consumer key and secret, and 4 URLS (Request token URL, Authorize URL , Access token URL and Callback URL ), so make a note of these, I&#8217;m assuming they may come in useful. Also note twitter&#8217;s &#8220;rules of the road&#8221;, which include things like display of a users twitter avatar if you&#8217;re using the twitter login mechanism, I&#8217;m not sure if Facebook makes the same requirement but if so will have to check.</p>
<h2>Get Twitter4j</h2>
<p>I&#8217;ll be using twitter4j to do a lot of the work, I&#8217;m already using it elsewhere, and been very happy so far with it&#8217;s ease of use.</p>
<p><a title="http://twitter4j.org/en/index.html" href="http://twitter4j.org/en/index.html">http://twitter4j.org/en/index.html</a></p>
<p>I&#8217;ll be using the Sign in Via Twitter example as my guide (EDIT &#8211; I pretty much copy it)</p>
<p><a title="http://twitter4j.org/en/code-examples.html#signinwithtwitter" href="http://twitter4j.org/en/code-examples.html#signinwithtwitter">http://twitter4j.org/en/code-examples.html#signinwithtwitter</a></p>
<h2>Code</h2>
<p>The first thing to do is add a log in via twitter link to our webpage, unlike the facebook one which is a link to facebook, this will be a link to a servlet implemented by our app.</p>
<p>The example above uses the following link.</p>
<pre class="brush: plain; title: ; notranslate">
&lt;a href=&quot;TwitterLogin&quot;&gt;&lt;img src=&quot;./images/Sign-in-with-Twitter-darker.png&quot;/&gt;&lt;/a&gt;
</pre>
<p>Taking the Twitter4j example I then ended up with a TwitterLoginServlet (which maps to &#8220;TwitterLogin&#8221; linked to above) and a TwitterCallbackServlet.<br />
I did find I had to fix the code below to hardcode the URL of the call back servlet when the app was deployed, possibly because I&#8217;m using Nginx as a reverse proxy so it was ending up with 127.0.0.1 instead of the host name, maybe I could fix Nginx configuration to avoid this.<br />
Twitter properties is just a convenience class used in this demo to hold the properties given when the app was created, twitter4J would read in properties from a properties file on the class path by default.</p>
<pre class="brush: plain; title: ; notranslate">
package uk.co.mrdw.shiroexp.servlets;

import java.io.IOException;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.RequestToken;
import twitter4j.conf.ConfigurationBuilder;

public class TwitterLoginServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println( &quot;TwitterLoginServlet:doGet&quot; );
ConfigurationBuilder cb = new ConfigurationBuilder();

Properties props = new TwitterProperties().getProperties();
cb.setDebugEnabled(true)
.setOAuthConsumerKey((String)props.get(&quot;twitterConsumerKey&quot;))
.setOAuthConsumerSecret((String)props.get(&quot;twitterConsumerSecret&quot;))
.setOAuthRequestTokenURL((String)props.get(&quot;twitterRequestTokenURL&quot;))
.setOAuthAuthorizationURL((String)props.get(&quot;twitterAuthorizeURL&quot;))
.setOAuthAccessTokenURL((String)props.get(&quot;twitterAccessTokenURL&quot;));
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
request.getSession().setAttribute(&quot;twitter&quot;, twitter);
try {
StringBuffer callbackURL = request.getRequestURL();
System.out.println( &quot;TwitterLoginServlet:callbackURL:&quot;+callbackURL );
int index = callbackURL.lastIndexOf(&quot;/&quot;);
callbackURL.replace(index, callbackURL.length(), &quot;&quot;).append(&quot;/TwitterCallback&quot;);

RequestToken requestToken = twitter.getOAuthRequestToken(callbackURL.toString());
request.getSession().setAttribute(&quot;requestToken&quot;, requestToken);
System.out.println( &quot;requestToken.getAuthenticationURL():&quot;+requestToken.getAuthenticationURL() );
response.sendRedirect(requestToken.getAuthenticationURL());

} catch (TwitterException e) {
throw new ServletException(e);
}

}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
*      response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
System.out.println(&quot;Unexpected doPost ...&quot;);
}
}
</pre>
<p>and the callback servlet (URL it&#8217;s mapped to needs to match the callbackURL generated in the login servlet above) &#8230;</p>
<pre class="brush: plain; title: ; notranslate">
package uk.co.mrdw.shiroexp.servlets;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.auth.RequestToken;

public class TwitterCallbackServlet  extends HttpServlet {

private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Twitter twitter = (Twitter) request.getSession().getAttribute(&quot;twitter&quot;);
RequestToken requestToken = (RequestToken) request.getSession().getAttribute(&quot;requestToken&quot;);
System.out.println( &quot;TwitterCallbackServlet:requestToken:&quot;+requestToken);
String verifier = request.getParameter(&quot;oauth_verifier&quot;);
try {
twitter.getOAuthAccessToken(requestToken, verifier);
request.getSession().removeAttribute(&quot;requestToken&quot;);
} catch (TwitterException e) {
throw new ServletException(e);
}
response.sendRedirect(request.getContextPath() + &quot;/&quot;);
}
}
</pre>
<p>This is pretty much a straight copy of the Twitter4J example.</p>
<p>Just to prove it was working I was able to add the following to the index.jsp</p>
<pre class="brush: plain; title: ; notranslate">
&lt;%
&lt;%@ page import=&quot;twitter4j.Twitter&quot;%&gt;
&lt;%@ page import=&quot;twitter4j.ProfileImage&quot;%&gt;

....

Twitter twitter = (Twitter) request.getSession().getAttribute(&quot;twitter&quot;);
if(twitter!=null){
String imageUrl = &quot;&quot;;
try {
imageUrl = twitter.getProfileImage(twitter.getScreenName(), ProfileImage.NORMAL).getURL();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
%&gt;
&lt;p&gt;Twitter ID:&lt;%=twitter.getId()%&gt;&lt;/p&gt;
&lt;p&gt;Twitter Screen Name:&lt;%=twitter.getScreenName()%&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;&lt;%=imageUrl %&gt;&quot;/&gt;
&lt;/p&gt;
&lt;%
}
%&gt;
</pre>
<p>So that&#8217;s the basics of a twitter login to a Java web application working &#8211; I know it&#8217;s not actually logging in via Shiro at them moment, or doing anything useful, that will come ( I&#8217;ll also need to check the Twitter &#8220;Rules of the Road&#8221; before deploying and make sure I&#8217;m complying).</p>
<p>Haven&#8217;t looked at what there is in common with the Facebook login yet from a point of view of making the Shiro implementation more generic,<br />
but I can see differences:<br />
Unlike the Facebook example this works wherever its deployed &#8211; Facebook uses the URL configured for the application to call back to.<br />
The login link on the web page goes to the web app, not to twitter.<br />
Using Twitter4j has hidden a lot of the nuts and bolts, which is good, but may mean less chance of sharing OAuth code between Facebook and Twitter implementations.</p>
<p>Next step login via google I think, then try and put it all together in a Shiro implementation.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/170/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/170/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=170&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/11/29/twitter-login-to-a-java-web-application/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>Using Apache Shiro Security to allow login via Facebook &#8211; part 2</title>
		<link>http://mrdwnotes.wordpress.com/2011/11/28/using-apache-shiro-security-to-allow-login-via-facebook-part-2/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/11/28/using-apache-shiro-security-to-allow-login-via-facebook-part-2/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 12:53:29 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mrdwnotes.wordpress.com/?p=138</guid>
		<description><![CDATA[Using Apache Shiro So in part 1 I got a basic servlet that can be used to determine if a user has logged in via Facebook, and get hold of details like the Facebook users&#8217;s ID and name etc. Now comes configuring and extending Shiro to handle Facebook login. I&#8217;ve taken the approach of creating [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=138&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h2>Using Apache Shiro</h2>
<p>So in part 1 I got a basic servlet that can be used to determine if a user has logged in via Facebook, and get hold of details like the Facebook users&#8217;s ID and name etc.</p>
<p>Now comes configuring and extending Shiro to handle Facebook login.</p>
<p>I&#8217;ve taken the approach of creating a new realm for Facebook, which will use a custom CredentialsMatcher (which won&#8217;t actually have to do much as it&#8217;s Facebook that handles any credentials matching). So with two new classes to be written uk.co.mrdw.security.facebook.FacebookCredentialsMatcher and uk.co.mrdw.security.facebook.FacebookRealm the config in shiro.ini (or embedded in web.xml in the tutorial) will have the following &#8220;main&#8221; section.</p>
<pre class="brush: plain; title: ; notranslate">
[main]
 realmA = name.brucephillips.somesecurity.dao.RoleSecurityJdbcRealm
 fbCredentialsMatcher = uk.co.mrdw.shiro.facebook.FacebookCredentialsMatcher
 realmB = uk.co.mrdw.security.facebook.FacebookRealm
 realmB.credentialsMatcher = $fbCredentialsMatcher
 securityManager.realms = $realmA, $realmB

</pre>
<p>(Maybe realmA and and realmB could be better named)</p>
<p>So shiro will first try realmA (the jdbc realm, backed by a users table), and if that realm doesn&#8217;t support the token being passed in to the             SecurityUtils.getSubject().login(token) it will try realmB, the Facebook realm. So we&#8217;ll need a new token class for Facebook to identify facebook logins.</p>
<p>The code in the authenticate method in the FacebookLoginServlet will be moved to the FacebookRealm class, and the FacebookLoginServlet will just create a Facebook token and call SecurityUtils.getSubject().login(token).</p>
<p>So we end up with a FacebookRealm class like this</p>
<pre class="brush: java; title: ; notranslate">

package uk.co.mrdw.shiro.facebook;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import uk.co.mrdw.shiroexp.servlets.FacebookProperties;

public class FacebookRealm extends AuthorizingRealm {

private static final Properties props = new FacebookProperties().getProperties();
private static final String APP_SECRET = props.get(&quot;fbAppSecret&quot;).toString();
private static final String APP_ID = props.get(&quot;fbAppId&quot;).toString();
private static final String REDIRECT_URL = props.get(&quot;fbLoginRedirectURL&quot;).toString();

@Override
public boolean supports(AuthenticationToken token) {
if (token instanceof FacebookToken) {
return true;
}
return false;
}

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return new FacebookAuthorizationInfo();
}

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
FacebookToken facebookToken = (FacebookToken) token;

// do all the facebook gubbins
if (facebookToken.getCode() != null &amp;&amp; facebookToken.getCode().trim().length() &gt; 0) {
URL authUrl;
try {
authUrl = new URL(&quot;https://graph.facebook.com/oauth/access_token?&quot; + &quot;client_id=&quot; + APP_ID
+ &quot;&amp;redirect_uri=&quot; + REDIRECT_URL + &quot;&amp;client_secret=&quot; + APP_SECRET + &quot;&amp;code=&quot;
+ facebookToken.getCode());

String authResponse = readURL(authUrl);
System.out.println(authResponse);
String accessToken = getPropsMap(authResponse).get(&quot;access_token&quot;);
URL url = new URL(&quot;https://graph.facebook.com/me?access_token=&quot; + accessToken);
String fbResponse = readURL(url);
FacebookUserDetails fud = new FacebookUserDetails(fbResponse);
return new FacebookAuthenticationInfo(fud, this.getName());
} catch (MalformedURLException e1) {
e1.printStackTrace();
throw new AuthenticationException(e1);
} catch (IOException ioe) {
ioe.printStackTrace();
throw new AuthenticationException(ioe);
} catch (Throwable e) {
e.printStackTrace();
}
}
return null;
}

// ------------------------------------------------------------
// STUFF here should be in a more generic place TODO
// ------------------------------------------------------------

private String readURL(URL url) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = url.openStream();
int r;
while ((r = is.read()) != -1) {
baos.write(r);
}
return new String(baos.toByteArray());
}

private Map&lt;String, String&gt; getPropsMap(String someString) {
String[] pairs = someString.split(&quot;&amp;&quot;);
Map&lt;String, String&gt; props = new HashMap&lt;String, String&gt;();
for (String propPair : pairs) {
String[] pair = propPair.split(&quot;=&quot;);
props.put(pair[0], pair[1]);
}
return props;
}
}

</pre>
<p>I have also added some getters to the FacebookUserDetails class &#8211; just extracting data from the json String it&#8217;s created with, will be refined as required in the future.</p>
<pre class="brush: plain; title: ; notranslate">
&lt;pre&gt;
package uk.co.mrdw.shiro.facebook;

import org.json.JSONException;
import org.json.JSONObject;

/**
* Simple class for holding data relating to a facebook user
*
* @author Mike
*
*/
public class FacebookUserDetails {
private String id;
private String firstName;
private String lastName;
private String email;
// jsonString Expected to be something like this
// {
// &quot;education&quot;: [{
// &quot;school&quot;: {
// &quot;id&quot;: &quot;123456789012345&quot;,
// &quot;name&quot;: &quot;University of Sheffield&quot;
// },
// &quot;type&quot;: &quot;Graduate School&quot;,
// &quot;with&quot;: [{
// &quot;id&quot;: &quot;123456789&quot;,
// &quot;name&quot;: &quot;Daffy Duck&quot;
// }]
// }],
// &quot;first_name&quot;: &quot;Mike&quot;,
// &quot;id&quot;: &quot;121212121&quot;,
// &quot;last_name&quot;: &quot;Warren&quot;,
// &quot;link&quot;:
// &quot;http://www.facebook.com/profile.php?id=121212121&quot;,
// &quot;locale&quot;: &quot;en_US&quot;,
// &quot;name&quot;: &quot;Mike Warren&quot;,
// &quot;updated_time&quot;: &quot;2011-08-15T14:51:05+0000&quot;,
// &quot;verified&quot;: true
// }
private String jsonString;

public FacebookUserDetails(String fbResponse){
jsonString = fbResponse;
JSONObject respjson;
try {
respjson = new JSONObject(fbResponse);
this.id = respjson.getString(&quot;id&quot;);
this.firstName = respjson.has(&quot;first_name&quot;) ? respjson.getString(&quot;first_name&quot;) : &quot; no name&quot; + id;
this.lastName = respjson.has(&quot;last_name&quot;) ? respjson.getString(&quot;last_name&quot;) : &quot;&quot;;
this.email = respjson.has(&quot;email&quot;) ? respjson.getString(&quot;email&quot;) : &quot;-no email-&quot;;
} catch (JSONException e) {
System.out.println( &quot;fbResponse:&quot;+fbResponse );
e.printStackTrace();
throw new RuntimeException(e);
}

}

public String toString(){
return jsonString;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}

</pre>
<p>The CredentialsMatcher class shouldn&#8217;t need to do anything, as Facebook is doing the credentials matching for us.</p>
<pre class="brush: plain; title: ; notranslate">
package uk.co.mrdw.shiro.facebook;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;

public class FacebookCredentialsMatcher implements CredentialsMatcher {

/**
* Just confirms that token is the right type - credentials checking is done by facebook OAuth
*/
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
if(info instanceof FacebookAuthenticationInfo){
return true;
}
return false;
}

}

</pre>
<p>create a facebook token class, will just be used to hold the &#8220;code&#8221; provided by Facebook</p>
<pre class="brush: plain; title: ; notranslate">
package uk.co.mrdw.shiro.facebook;

import org.apache.shiro.authc.AuthenticationToken;

public class FacebookToken implements AuthenticationToken {

private static final long serialVersionUID = 1L;
private String code;

public FacebookToken(String code){
this.code = code;
}

@Override
public Object getPrincipal() {
return null;// not known - facebook does the login
}

@Override
public Object getCredentials() {
return null;// credentials handled by facebook - we don't need them
}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}
}
</pre>
<p>And a FacebookAuthenticationInfo class</p>
<pre class="brush: plain; title: ; notranslate">
package uk.co.mrdw.shiro.facebook;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

public class FacebookAuthenticationInfo implements AuthenticationInfo {

private static final long serialVersionUID = 1L;

private PrincipalCollection principalCollection;

public FacebookAuthenticationInfo(FacebookUserDetails facebookUserDetails, String realmName){
Collection&lt;String&gt; principals = new ArrayList&lt;String&gt;();
principals.add(facebookUserDetails.getId());
principals.add(facebookUserDetails.getFirstName()+&quot; &quot;+facebookUserDetails.getLastName()); // Is this appropriate is the name not really a Principal ?
this.principalCollection = new SimplePrincipalCollection(principals, realmName);
}

@Override
public PrincipalCollection getPrincipals() {
return principalCollection;
}

@Override
public Object getCredentials() {
return null;// no credentials required
}
}

</pre>
<p>The FacebookLoginServlet then becomes much simpler &#8211; basically just use&#8217;s Shiro&#8217;s login mechanism.</p>
<pre class="brush: plain; title: ; notranslate">
package uk.co.mrdw.shiroexp.servlets;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;

import uk.co.mrdw.shiro.facebook.FacebookToken;

/**
* Simple Facebook Login Handling, doesn't actually do anything except display page confirming login
* successfull.
*
*
* @author Mike
*
*/
public class FacebookLoginServlet  extends HttpServlet {

private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(&quot;FacebookLoginServlet getting..&quot;);

String code = request.getParameter(&quot;code&quot;);
FacebookToken facebookToken = new FacebookToken(code);
try{
SecurityUtils.getSubject().login(facebookToken);
response.sendRedirect(response.encodeRedirectURL(&quot;index.jsp&quot;));
}
catch(AuthenticationException ae){
throw new ServletException(ae);
}
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
*      response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
System.out.println(&quot;Unexpected doPost ...&quot;);
}
}

</pre>
<p>I&#8217;ve added a few lines to index.jsp, just to give some feedback on the result of the login via facebook</p>
<pre class="brush: plain; title: ; notranslate">
&lt;%@ page import=&quot;org.apache.shiro.SecurityUtils&quot;%&gt;
&lt;%@ page import=&quot;org.apache.shiro.subject.PrincipalCollection&quot;%&gt;

...

&lt;p&gt;Is authenticated? &lt;%= SecurityUtils.getSubject().isAuthenticated() %&gt;&lt;/p&gt;
&lt;p&gt;Principal:&lt;%= SecurityUtils.getSubject().getPrincipal() %&gt;&lt;/p&gt;
&lt;p&gt;Principals:&lt;/p&gt;
&lt;% PrincipalCollection principalCollection = SecurityUtils.getSubject().getPrincipals();
if(principalCollection!=null){
for(Object principal : principalCollection.asList()){
//request.out.println(&quot;&lt;p&gt;&quot;+principal +&quot;&lt;/p&gt;&quot;);
%&gt;&lt;p&gt;&lt;%=principal %&gt;&lt;/p&gt;&lt;%
}
}
%&gt;
</pre>
<p>which ends up with output like this</p>
<pre class="brush: plain; title: ; notranslate">&lt;/pre&gt;
Is authenticated? true

Principal:121212121

Principals:

121212121

Mike Warren
&lt;pre&gt;
</pre>
<p>And that&#8217;s it &#8211; have just tested it and it works, I can login via facebook and get access to the &#8220;secure&#8221; page, get a display of the facebook ID as the principal, and can logout via the standard logout link.<br />
Think I may need to read up on Principals and Roles a bit to see how to integrate shiro authorization capabilities with what I&#8217;ve got, but it may be that this is enough for my currrent needs.</p>
<p>I have a few doubts about whether this is the right way to use Shiro, so may well post a follow up post &#8211; &#8220;Using Shiro properly&#8221; to correct mistakes here.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/138/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=138&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/11/28/using-apache-shiro-security-to-allow-login-via-facebook-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>Using Apache Shiro Security to allow login via Facebook &#8211; part 1</title>
		<link>http://mrdwnotes.wordpress.com/2011/11/28/using-apache-shiro-security-to-allow-login-via-facebook-part-1/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/11/28/using-apache-shiro-security-to-allow-login-via-facebook-part-1/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 12:53:01 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mrdwnotes.wordpress.com/?p=117</guid>
		<description><![CDATA[Background Having got Facebook login working for my message board project in a quick and dirty way I decided to try and switch to using Apache Shiro for my security needs. This should hopefully mean I end up with something a bit more maintainable that could be extended without ending up with a custom made [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=117&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h2>Background</h2>
<p>Having got Facebook login working for my message board project in a quick and dirty way I decided to try and switch to using Apache Shiro for my security needs. This should hopefully mean I end up with something a bit more maintainable that could be extended without ending up with a custom made mess.</p>
<p>I&#8217;ve now got Shiro working in the message board project, and it has been pretty straighforward to get it running wityh a database tables of users,roles and passwords (encyrpted of course). After looking at the documentation on the Apache Shiro site I&#8217;d recommend the tutorial by Bruce Phillips <a href="http://www.brucephillips.name/blog/index.cfm/2009/4/5/An-Introduction-to-Ki-formerly-JSecurity&#8211;A-Beginners&#8211;Tutorial-Part-1" rel="nofollow">http://www.brucephillips.name/blog/index.cfm/2009/4/5/An-Introduction-to-Ki-formerly-JSecurity&#8211;A-Beginners&#8211;Tutorial-Part-1</a></p>
<p>Next step was to allow login via facebook (hoping to add other logins for twitter, google etc. soon) . I have a rough version of facebook login using Shiro working on my message board, but I&#8217;m not 100% sure about my approach, so rather than steam ahead with what I&#8217;ve done I&#8217;m going to try taking a step back and add facebook login to the tutorial project Bruce Phillips has created. At least then I can use this for demonstrating to others what I&#8217;ve done, which may be useful for anyone else trying something similar, and also have a simple project that I can experiment with without worrying about other distractions.</p>
<p>So bear in mind that this is my first rough stab at Facebook login with Shiro, I&#8217;m new to Shiro and to OAuth/Facebook login, so may well be setting a bad example, if so hopefully I&#8217;ll learn and be able to post a follow up with a better way of doing it. Basically feel free to copy stuff hear, but don&#8217;t blame me if it&#8217;s wrong.</p>
<p>I got some inspiration from Tynamo , which is a Tapestry module for doing exactly this</p>
<p><a title="http://tynamo.org/tynamo-federatedaccounts+guide" href="http://tynamo.org/tynamo-federatedaccounts+guide" target="_blank">http://tynamo.org/tynamo-federatedaccounts+guide</a></p>
<p>which I came accross in the Shiro user forum here</p>
<p><a title="http://shiro-user.582556.n2.nabble.com/Advice-on-Shira-with-FB-Connect-Session-Clustering-Efficiency-td6832777.html" href="http://shiro-user.582556.n2.nabble.com/Advice-on-Shira-with-FB-Connect-Session-Clustering-Efficiency-td6832777.html" target="_blank">http://shiro-user.582556.n2.nabble.com/Advice-on-Shira-with-FB-Connect-Session-Clustering-Efficiency-td6832777.html</a></p>
<h2>Adding Facebook Login to &#8220;Somesecurity&#8221; Tutorial App</h2>
<p>So copied the &#8220;somescurity&#8221; project in Eclipse to a new ShiroFacebook project ( found I had to go to &#8220;project-&gt;properties-&gt;Web Project Settings&#8221; and change the context root).</p>
<h3>Create a Facebook App</h3>
<p>This requires you to have URL where the app will be deployed.</p>
<p>In Facebook  <a title="https://developers.facebook.com/apps" href="https://developers.facebook.com/apps" target="_blank">https://developers.facebook.com/apps</a> select development, and create an App.</p>
<p>First you need to come up with a display name and a namespace for the app.</p>
<p>Then in the Website &#8220;I want to allow people to log into my website using Facebook&#8221; section you need to provide the URL for your app.</p>
<p>You should then have an App ID, and an App Secret for your application &#8211; make a note of these.</p>
<h3>Add Login Via Facebook Link</h3>
<p>Next add a login via facebook link on index.jsp , which will be like this.</p>
<p><a href="https://www.facebook.com/dialog/oauth?client_id=123456789012345&#038;redirect_uri=http://www.somesite.co.uk/shirofb/FacebookLogin" rel="nofollow">https://www.facebook.com/dialog/oauth?client_id=123456789012345&#038;redirect_uri=http://www.somesite.co.uk/shirofb/FacebookLogin</a></p>
<p>Where an &#8220;App ID&#8221; of 123456789012345 and the application will be running at <a href="http://www.somesite.co.uk/shirofb" rel="nofollow">http://www.somesite.co.uk/shirofb</a> .</p>
<h3>Create FacebookLogin Servlet</h3>
<p>Now we need to create a FacebookLogin servlet to handle the redirection from Facebook.</p>
<p>I found this blog post very helpful:</p>
<p><a title="http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/" href="http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/" target="_blank">http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/</a></p>
<p>So from Richard Nichol&#8217;s blog above and reading Facebook documentation I&#8217;ve ended with the follow servlet .</p>
<p>Facebook sends a request to this servlet after a user has clicked on the facebook login link on our index.jsp, this request contains a code which is used in the authenticate method to request an access token from facebook, which can be used to get details (id, name etc. ) of the user who has logged in. The Servlet then just prints out a simple piece of html to display the users details, or an error message.</p>
<pre class="brush: java; title: ; notranslate">
&lt;pre&gt;package uk.co.mrdw.shiroexp.servlets;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Simple Facebook Login Handling, doesn't actually do anything except display page confirming login
* successfull.
*
*
* @author Mike
*
*/
public class FacebookLoginServlet  extends HttpServlet {

private static final long serialVersionUID = 1L;

/**
* Properties will be as follows, but with values for this app.
* fbAppSecret=1a234bc1234d1234e1f123g1234567g1
* fbAppId=123456789012345
* fbLoginRedirectURL=http://www.yoursite.co.uk/shirofb/FacebookLogin
*/
private static final Properties props = new FacebookProperties().getProperties();

private static final String APP_SECRET = props.get(&quot;fbAppSecret&quot;).toString();
private static final String APP_ID = props.get(&quot;fbAppId&quot;).toString();
private static final String REDIRECT_URL = props.get(&quot;fbLoginRedirectURL&quot;).toString();

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(&quot;FacebookLoginServlet getting..&quot;);

FacebookUserDetails fud = authenticate(request, response);

if (fud != null) {
response.getWriter().write(&quot;&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;h1&gt;Facebook Logged In&lt;/h1&gt;&lt;p&gt;&quot;+fud.toString()+&quot;&lt;/p&gt;&lt;/body&gt;&quot;);
response.getWriter().flush();

} else {
try {
System.out.println(&quot;fb log in failed&quot;);
String errorReason = request.getParameter(&quot;error_reason&quot;);
String error = request.getParameter(&quot;error&quot;);
response.getWriter().write(&quot;&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;h1&gt;fb login failed&lt;/h1&gt;&quot; +
&quot; reason:&quot;+errorReason+&quot; error:&quot;+error+&quot;&lt;/body&gt;&quot;);
response.getWriter().flush();

return;
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
*      response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
System.out.println(&quot;Unexpected doPost ...&quot;);
}

/**
* Makes call to Facebook to get access_token, and then to get id, name etc.
* for the facebook user relating to that token. Returns FacebookUserDetails
* object for that user, or null if unable to complete authentication.
*
* @param request
* @param response
* @param code
* @return FacebookUserDetails
* @throws MalformedURLException
* @throws IOException
*/
private FacebookUserDetails authenticate(HttpServletRequest request, HttpServletResponse response)
throws MalformedURLException, IOException {
FacebookUserDetails fud = null;
String code = request.getParameter(&quot;code&quot;);
if (code != null &amp;&amp; code.trim().length() &gt; 0) {
URL authUrl = new URL(&quot;https://graph.facebook.com/oauth/access_token?&quot; + &quot;client_id=&quot;
+ APP_ID + &quot;&amp;redirect_uri=&quot; + REDIRECT_URL + &quot;&amp;client_secret=&quot;
+ APP_SECRET + &quot;&amp;code=&quot; + code);

String authResponse = readURL(authUrl);
System.out.println(authResponse);

try {
String accessToken = getPropsMap(authResponse).get(&quot;access_token&quot;);
URL url = new URL(&quot;https://graph.facebook.com/me?access_token=&quot; + accessToken);
String fbResponse = readURL(url);

System.out.println(fbResponse);

fud = new FacebookUserDetails(fbResponse);

} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
return fud;
}

private String readURL(URL url) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = url.openStream();
int r;
while ((r = is.read()) != -1) {
baos.write(r);
}
return new String(baos.toByteArray());
}

private Map&lt;String, String&gt; getPropsMap(String someString) {
String[] pairs = someString.split(&quot;&amp;&quot;);
Map&lt;String, String&gt; props = new HashMap&lt;String, String&gt;();
for (String propPair : pairs) {
String[] pair = propPair.split(&quot;=&quot;);
props.put(pair[0], pair[1]);
}
return props;

}

/**
* Simple class for holding data relating to a facebook user
* currentyl just holds jsonString, but could have extra properties added backed by the json
* e.g. id, firstName, lastName, link ,education[], etc.
*
* @author Mike
*
*/
class FacebookUserDetails {

// jsonString Expected to be something like this, although I'm sure it used to include
// email
// {
// &quot;education&quot;: [{
// &quot;school&quot;: {
// &quot;id&quot;: &quot;123456789012345&quot;,
// &quot;name&quot;: &quot;University of Sheffield&quot;
// },
// &quot;type&quot;: &quot;Graduate School&quot;,
// &quot;with&quot;: [{
// &quot;id&quot;: &quot;123456789&quot;,
// &quot;name&quot;: &quot;Daffy Duck&quot;
// }]
// }],
// &quot;first_name&quot;: &quot;Mike&quot;,
// &quot;id&quot;: &quot;121212121&quot;,
// &quot;last_name&quot;: &quot;Warren&quot;,
// &quot;link&quot;:
// &quot;http://www.facebook.com/profile.php?id=121212121&quot;,
// &quot;locale&quot;: &quot;en_US&quot;,
// &quot;name&quot;: &quot;Mike Warren&quot;,
// &quot;updated_time&quot;: &quot;2011-08-15T14:51:05+0000&quot;,
// &quot;verified&quot;: true
// }
private String jsonString;

FacebookUserDetails(String fbResponse){
jsonString = fbResponse;
}

public String toString(){
return jsonString;
}
}

}
</pre>
<p>&#8230; Next Part 2 Making use of Shiro</p>
<p><span id="more-117"></span><!--more--></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/117/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=117&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/11/28/using-apache-shiro-security-to-allow-login-via-facebook-part-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>Welcome to wordpress.com</title>
		<link>http://mrdwnotes.wordpress.com/2011/11/28/welcome-to-wordpress-com/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/11/28/welcome-to-wordpress-com/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 12:38:27 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mrdwnotes.wordpress.com/?p=165</guid>
		<description><![CDATA[Just a quick post to confirm move from mrdw.co.uk/blog has happened &#8211; decided that wordpress probably have more experience than myself in hosting a blog, (saves me from having to update wordpress install etc.)<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=165&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Just a quick post to confirm move from mrdw.co.uk/blog has happened &#8211; decided that wordpress probably have more experience than myself in hosting a blog, (saves me from having to update wordpress install etc.)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/165/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=165&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/11/28/welcome-to-wordpress-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>Another TODO List</title>
		<link>http://mrdwnotes.wordpress.com/2011/09/25/another-todo-list/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/09/25/another-todo-list/#comments</comments>
		<pubDate>Sun, 25 Sep 2011 12:39:46 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mrdw.co.uk/blog/?p=109</guid>
		<description><![CDATA[I&#8217;ve completed the last todo list for the running club message board, including a few extras that I added on the way, but have also added many more things to my mental (as in held in my mind, but maybe also MENTAL) todo list, so nows I good time to write them down so I [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=109&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve completed the last todo list for the running club message board, including a few extras that I added on the way, but have also added many more things to my mental (as in held in my mind, but maybe also MENTAL) todo list, so nows I good time to write them down so I can tick them off as I go.</p>
<p>&nbsp;</p>
<ol>
<li>Tidy up code, not aiming for it to be perfect but having the luxury of just hacking away with getting functionality working quickly as the main driver it could do with being tidied up before attempting anymore work on it.</li>
<li>Templating: At the moment theres hardcoding, so will only work for one messageboard, but I want to set up another one for testing, one for demonstration, and also another running club have one that is still on the old PHP code so would be nice to update that, shouldn&#8217;t be too hard, be nice to just have a properties file that I can switch.</li>
<li>Use Github: I&#8217;ve been using Codesion for some subversion hosting, but the pricing doesn&#8217;t really make sense for small projects that aren&#8217;t expected to make any money, so having used up my allowance of projects I&#8217;ve resorted to backing up a zip file. Github looks good, I&#8217;m happy to make the code public, and also feel like I should make the effort to try Git.</li>
<li>Allow login through other services &#8211; google/twitter/yahoo etc., I don&#8217;t like Facebook so be good to  not be encourageing people to use it even more.</li>
<li>Make the login system create actual users and generally be better, it works as it is but its about as basic as you can get &#8211; you&#8217;re logged in or not, but everyone effectively logs in as same user, but just gives a different name to their post.</li>
<li>Admin users &#8211; need to be able to have administrators that can delete posts etc.</li>
<li>Allow editing of posts/replies you&#8217;ve just created,  not sure about going back and editing old messages, but should be able to use the session to allow editing of something that&#8217;s just been posted, which is when people normally spot typos.</li>
</ol>
<p>That will do for starters, got loads of other stuff in I&#8217;d like to do, be good to start using it as a basis for trying / evaluating different technologies &#8211; and brushing up things I&#8217;ve got on my CV. For example using JPA, Spring, Shiro. Then be good to try a Ruby version, a google app engine version and things I&#8217;ve only just heard of Node and Mongodb &#8230;</p>
<p>A Facebook app that&#8217;s worse than Farmville is also on my mental list.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/109/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=109&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/09/25/another-todo-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>Facebook Login</title>
		<link>http://mrdwnotes.wordpress.com/2011/09/22/facebook-login/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/09/22/facebook-login/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 21:28:49 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mrdw.co.uk/blog/?p=105</guid>
		<description><![CDATA[Got Facebook login working yesterday. It&#8217;s been a while since I posted so thought I should do a quick one whilst I&#8217;ve got time.  I&#8217;ve got an idea to go back over the various tasks involved in getting the message board running and write them up as proper &#8220;how to&#8221; blog posts that might actually [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=105&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Got Facebook login working yesterday.</p>
<p>It&#8217;s been a while since I posted so thought I should do a quick one whilst I&#8217;ve got time.  I&#8217;ve got an idea to go back over the various tasks involved in getting the message board running and write them up as proper &#8220;how to&#8221; blog posts that might actually be useful to someone, or at least me if I forget how I did it.</p>
<p>Anyway, I got facebook login working, after a bit of googling and reading through the facebook developer documentation. I have resorted to dropping the Spring login stuff, which I&#8217;d used to allow ajax logins to work with standard J2EE security. As I couldn&#8217;t find away of getting the standard J2EE security to work with logins from Facebook (not facebook specific &#8211; would have had the same problem with any OAuth login I think). I did try the new(ish) HttpServletRequest.login method available in Servlet API 3.0 &#8211; Tomcat 7.0, but found it only seemed to login that request, not the session, so when the response redirected the user to the message board after the facebook login they were still logged out as far as the session was concerned. So I&#8217;ve done what feels like a quick hack and just stored a &#8220;logged in&#8221; flag in the session.</p>
<p>I will investigate Apache Shiro, <a href="http://shiro.apache.org/" rel="nofollow">http://shiro.apache.org/</a> , an alternative to J2EE security. I&#8217;m not convinced J2EE standard is flexible enough for most uses I&#8217;m likely to come accross in the real world, but maybe I&#8217;m missing something, but it seems as though the creator of Shiro thought the same.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/105/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=105&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/09/22/facebook-login/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>Twitter me not</title>
		<link>http://mrdwnotes.wordpress.com/2011/08/17/twitter-me-not/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/08/17/twitter-me-not/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 21:25:45 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mrdw.co.uk/blog/?p=100</guid>
		<description><![CDATA[So in the past I&#8217;d used Twitter4J to work with twitter, and it had proved to be very simple, and just work. For example the give a userid and password for twitter I could just write code as follows to do an update. Twitter twitter = new Twitter(twitterID,twitterPassword); twitter.setSource(&#8220;mikewarrenstwitterprogram&#8221;); Status status = twitter.update( responseString ); [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=100&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>So in the past I&#8217;d used Twitter4J to work with twitter, and it had proved to be very simple, and just work.</p>
<p>For example the give a userid and password for twitter I could just write code as follows to do an update.</p>
<p>Twitter twitter = new Twitter(twitterID,twitterPassword);<br />
twitter.setSource(&#8220;mikewarrenstwitterprogram&#8221;);</p>
<p>Status status = twitter.update( responseString );</p>
<p>Seems things have moved on, and there&#8217;s a whole load of configuration required to be able to authenticate programatically with Twitter. I&#8217;m not sure why exactly, because if I use a twitter client all I need to give it is username and password, but I&#8217;m sure there&#8217;s a good reason  &#8230; just need to find out how and why, which means what I thought would be a 10 minute bit of work will be as long as a piece of string &#8211; that&#8217;s computing for you.</p>
<p>&nbsp;</p>
<p>Looks like I need to start with <a href="https://dev.twitter.com/docs/auth" rel="nofollow">https://dev.twitter.com/docs/auth</a></p>
<p>&nbsp;</p>
<h2>Update 22/09/2011:</h2>
<p>Just a quick note to say I got it working after jumping though a couple of hoops, using Twitter4J still, but you&#8217;re now forced to use OAuth to interact with Twitter.  Basically you need to authorise your app with the account you want to post to, and then set up access tokens and secrets etc. I&#8217;ll write it up as a nice &#8220;how to&#8221; blog post when I get round to it.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/100/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/100/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=100&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/08/17/twitter-me-not/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>Message Board #6 &#8211; Done</title>
		<link>http://mrdwnotes.wordpress.com/2011/08/16/message-board-6-done/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/08/16/message-board-6-done/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 22:22:29 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mrdw.co.uk/blog/?p=93</guid>
		<description><![CDATA[Well almost, I want to make a tweak or two before I make it available for use , but the work I originally listed back in April is done Switch to use the live DB currently being used by the PHP app. &#8211; DONE Make links automatically out of URLs in messages &#8211; DONE Clean [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=93&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Well almost, I want to make a tweak or two before I make it available for use , but the work I originally listed back in April is done</p>
<ul>
<li>Switch to use the live DB currently being used by the PHP app. &#8211; DONE</li>
<li>Make links automatically out of URLs in messages &#8211; DONE</li>
<li>Clean up html so it looks presentable (this could be a big one) &#8211; DONE</li>
<li>Either set up email notifications, or some alternative, e.g. posts to twitter &#8211; DONE</li>
</ul>
<p>I mainly want to change the URL that it&#8217;s using so that once it starts being used people can favourite a URL and not have it change a week later. Also although I&#8217;ve got email notifications, I&#8217;d like to add twitter posting as I know that&#8217;s pretty easy, and gives some advantage from a user&#8217;s point of view to the new version.</p>
<p>I&#8217;ve been tinkering with adding facebook &#8220;like&#8221; and google &#8220;plus 1&#8243;, but easy to do for the whole page, but not working for me when I try to make them refer to an individual post, so that&#8217;s another thing to add to the list.</p>
<p>Part of me can&#8217;t quite believe that it&#8217;s taken so long, but then it has been the just the odd bit of time here and there in between working, sleeping, and various recreational activitities, so part of me is pretty pleased to have done it. Blogging has be useful as a reminder of what progress I&#8217;ve made &#8211; important when it&#8217;s so slow, and also an incentive to at least try and do something every week or two.I intend to continue, documenting adding various features, refactoring and maybe trying out different languages/frameworks, keeping a low threshold on quality of what I write in the hope that will mean I do actually post something.</p>
<p>Now I can treat myself to a waterproof camera housing, although having spent this long I&#8217;m not sure how much I really want one &#8230;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/93/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=93&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/08/16/message-board-6-done/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>Message Board #5 &#8211; regexp</title>
		<link>http://mrdwnotes.wordpress.com/2011/07/05/message-board-5-regexp/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/07/05/message-board-5-regexp/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 22:50:42 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mrdw.co.uk/blog/?p=89</guid>
		<description><![CDATA[Not much to report again, in the little bit of time I&#8217;ve managed to grab I&#8217;ve been looking at the ake links automatically out of URLs in messages task. I&#8217;d already done this in PHP, and planned to do it in Java. After implementing the code to do it in a getter on my Message [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=89&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Not much to report again, in the little bit of time I&#8217;ve managed to grab I&#8217;ve been looking at the <strong>ake links automatically out of URLs in messages </strong> task.</p>
<p>I&#8217;d already done this in PHP, and planned to do it in Java. After implementing the code to do it in a getter on my Message class I realised the serialization done by com.google.gson.Gson.toJson wasn&#8217;t using the getter. After stopping to consider I decided it made more sense to do it in the code doing the actual display anyway, i.e. the javascript.</p>
<p>So looking into Javascript regular expressions and regular expressions for URLs I found this <a href="http://daringfireball.net/2010/07/improved_regex_for_matching_urls">http://daringfireball.net/2010/07/improved_regex_for_matching_urls</a> which looked pretty promising. But had trouble converting it into a javascript regexp (I think mainly due to some none ASCII characters, and the escaping of certain characters in Javascript), and had a feeling that it would actually be more lenient than I really want &#8211; e.g. I don&#8217;t want to match ftp.<br />
So resorted to just converting what I was doing in PHP, which is a bit inelegant, but seems to work. It uses three separate replaces to cater for URL&#8217;s starting with &#8220;<a href="http://&#038;#8221" rel="nofollow">http://&#038;#8221</a>; (but not www&#8217;s), then strips off any &#8220;<a href="http://&#038;#8221" rel="nofollow">http://&#038;#8221</a>; from www&#8217;s and then sorts out remaining urls starting with &#8220;www.&#8221;. I know one bug is that it seems to fail to match the url after a &#8220;www&#8221; on its own, and also with a bit of regexp skill I should be able to combine the 3 separate passes into one regular expression. </p>
<p>As a quick test I used this javascript: ( I definitely need to sort out WordPress displaying code)</p>
<p><code><br />
var data = "blah <a href="http://google.co.uk" rel="nofollow">http://google.co.uk</a> blah <a href="http://www.bbc.co.uk" rel="nofollow">http://www.bbc.co.uk</a> www <a href="http://www.mrdw.co.uk" rel="nofollow">http://www.mrdw.co.uk</a> <a href="http://www.bbc.co.uk" rel="nofollow">http://www.bbc.co.uk</a> blah <a href="http://www.bbc.co.uk" rel="nofollow">http://www.bbc.co.uk</a>  blah <a href="http://google.co.uk" rel="nofollow">http://google.co.uk</a>  /mb mike gahsj asghja";<br />
var reg1 = new RegExp("http://[^w][^w][^w][a-zA-Z0-9|_+-/?&amp;=.%:,~#]*","g");<br />
var data1 = data.replace(reg1, '<a href="&quot;$&amp;&quot;">$&amp;</a>');// deal with non www addresses that have a http://<br />
var reg2 = new RegExp("http://www.","g");<br />
var data2 = data1.replace(reg2, ' www.');// 1st strip off any <a href="http://www" rel="nofollow">http://www</a> to just www so next rule will work<br />
var reg3 = new RegExp("www.[a-zA-Z0-9|_+-/?&amp;=.%:,~#]*","gim");<br />
var data3 = data2.replace(reg3, '<a href="//$&amp;&quot;">$&amp;</a>');<br />
document.write(" </code></p>
<p><code>"+data1+"</code></p>
<p><code>");<br />
document.write("</p>
<p>"+data2+"</p>
<p>");<br />
document.write("</p>
<p>"+data3+"</p>
<p></code></p>
<p><code>");<br />
</code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/89/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=89&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/07/05/message-board-5-regexp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
		<item>
		<title>MessageBoard App #4 Email using Gmail and more nginx</title>
		<link>http://mrdwnotes.wordpress.com/2011/06/30/messageboard-app-4-email-using-gmail-and-more-nginx/</link>
		<comments>http://mrdwnotes.wordpress.com/2011/06/30/messageboard-app-4-email-using-gmail-and-more-nginx/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 21:25:41 +0000</pubDate>
		<dc:creator>mrmikewarren</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mrdw.co.uk/blog/?p=82</guid>
		<description><![CDATA[So as is traditional a quick reminder for myself of what my todo list was looking like: Switch to use the live DB currently being used by the PHP app. -mainly done &#8211; should be easy to switch over now Make links automatically out of URLs in messages Clean up html so it looks presentable [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=82&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>So as is traditional a quick reminder for myself of what my todo list was looking like:</p>
<li>Switch to use the live DB currently being used by the PHP app.<strong> -mainly done &#8211; should be easy to switch over now</strong>
</li>
<li>Make links automatically out of URLs in messages
</li>
<li>Clean up html so it looks presentable (this could be a big one)
</li>
<li>Either set up email notifications, or some alternative, e.g. posts to twitter <strong>proven in theory &#8211; using gmail</strong>
</li>
<li>Setup a domain name. <strong>done</strong>
</li>
<li>Setup a webserver, to stand in front of tomcat(which is running on port 8080) so can use port 80 (<strong>aka a reverse proxy server I&#8217;ve learnt</strong>) <strong>done, using nginx, but want to tidy up config and do some testing around logging in/out</strong> </li>
<p>So, as is traditional, I didn&#8217;t get to spend much time on it this week, if only I didn&#8217;t have any family or freinds or leisure activities I might have more time to write a crappy message board application. Oh well.</p>
<p>But have managed to prove that I should be able to use a gmail account to send notification emails from &#8211; not sure if this is an advantage or not over setting up an email server, but in the spirit of just getting something working in whatever way is easiest it does the job.</p>
<p>Also a bit of tweaking of nginx config seemed to be having no effect, despite &#8220;ctrl shift delete, delete all cache&#8221; in firefox, which stumped me till I found a default file in /etc/nginx/sites-available which was what seemed to be taking precedence. Or maybe nginx wasn&#8217;t reloading the config like I thought it was when I ran &#8220;nginx -s reload&#8221;. Anyway, it&#8217;s working now, but need to experiment a bit to be confident that I&#8217;ve got any sort of a clue as to why.</p>
<p>Code for emailing from Java using gmail (mostly from <a href="http://www.velocityreviews.com/forums/t141237-send-smtp-mail-using-javamail-with-gmail-account.html" rel="nofollow">http://www.velocityreviews.com/forums/t141237-send-smtp-mail-using-javamail-with-gmail-account.html</a><br />
) , sorry wordpress doesn&#8217;t format better &#8230;:<br />
<code><br />
package uk.co.mrdw.util;</p>
<p>import java.security.Security;<br />
import java.util.Date;<br />
import java.util.Properties;</p>
<p>import javax.mail.Message;<br />
import javax.mail.MessagingException;<br />
import javax.mail.PasswordAuthentication;<br />
import javax.mail.Session;<br />
import javax.mail.Transport;<br />
import javax.mail.internet.InternetAddress;<br />
import javax.mail.internet.MimeMessage;</p>
<p>/**<br />
 * based on code here<br />
 * <a href="http://www.velocityreviews.com/forums/t141237-send-smtp-mail-using-javamail-with-gmail-account.html" rel="nofollow">http://www.velocityreviews.com/forums/t141237-send-smtp-mail-using-javamail-with-gmail-account.html</a><br />
 * @author Mike<br />
 *<br />
 */<br />
public class Emailer {<br />
	private static final String SMTP_HOST_NAME = "smtp.gmail.com";<br />
	private static final String SMTP_PORT = "465";<br />
	private static final String emailMsgTxt = "Test Message Contents";<br />
	private static final String emailSubjectTxt = "A test from gmail";<br />
	private static final String emailFromAddress = "xxxxxxxxxx@gmail.com";<br />
	private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";<br />
	private static final String[] sendTo = { "yyyyyyy@gmail.com"};</p>
<p>	public static void main(String args[]) throws Exception {</p>
<p>		Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());</p>
<p>		new Emailer().sendSSLMessage(sendTo, emailSubjectTxt,<br />
				emailMsgTxt, emailFromAddress);<br />
		System.out.println("Sucessfully Sent mail to All Users");<br />
	}</p>
<p>	public void sendSSLMessage(String recipients[], String subject,<br />
			String message, String from) throws MessagingException {<br />
		boolean debug = true;</p>
<p>		Properties props = new Properties();<br />
		props.put("mail.smtp.host", SMTP_HOST_NAME);<br />
		props.put("mail.smtp.auth", "true");<br />
		props.put("mail.debug", "true");<br />
		props.put("mail.smtp.port", SMTP_PORT);<br />
		props.put("mail.smtp.socketFactory.port", SMTP_PORT);<br />
		props.put("mail.smtp.socketFactory.class", SSL_FACTORY);<br />
		props.put("mail.smtp.socketFactory.fallback", "false");</p>
<p>		Session session = Session.getDefaultInstance(props,<br />
				new javax.mail.Authenticator() {</p>
<p>			protected PasswordAuthentication getPasswordAuthentication() {<br />
				return new PasswordAuthentication("xxxxxxxxxxx@gmail.com", "PASSWORD");<br />
			}<br />
		});</p>
<p>		session.setDebug(debug);</p>
<p>		Message msg = new MimeMessage(session);<br />
		InternetAddress addressFrom = new InternetAddress(from);<br />
		msg.setFrom(addressFrom);</p>
<p>		InternetAddress[] addressTo = new InternetAddress[recipients.length];<br />
		for (int i = 0; i &lt; recipients.length; i++) {<br />
			addressTo[i] = new InternetAddress(recipients[i]);<br />
		}<br />
		msg.setRecipients(Message.RecipientType.TO, addressTo);</p>
<p>		// Setting the Subject and Content Type<br />
		msg.setSubject(subject);<br />
		msg.setContent(message, &quot;text/plain&quot;);<br />
		Transport.send(msg);<br />
	}<br />
}<br />
</code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrdwnotes.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrdwnotes.wordpress.com/82/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrdwnotes.wordpress.com&#038;blog=29808387&#038;post=82&#038;subd=mrdwnotes&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrdwnotes.wordpress.com/2011/06/30/messageboard-app-4-email-using-gmail-and-more-nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/fca20f14a7459b3c6df7f1bb2458cfc4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrmikewarren</media:title>
		</media:content>
	</item>
	</channel>
</rss>
