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 mess.
I’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’d recommend the tutorial by Bruce Phillips http://www.brucephillips.name/blog/index.cfm/2009/4/5/An-Introduction-to-Ki-formerly-JSecurity–A-Beginners–Tutorial-Part-1
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’m not 100% sure about my approach, so rather than steam ahead with what I’ve done I’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’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.
So bear in mind that this is my first rough stab at Facebook login with Shiro, I’m new to Shiro and to OAuth/Facebook login, so may well be setting a bad example, if so hopefully I’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’t blame me if it’s wrong.
I got some inspiration from Tynamo , which is a Tapestry module for doing exactly this
http://tynamo.org/tynamo-federatedaccounts+guide
which I came accross in the Shiro user forum here
Adding Facebook Login to “Somesecurity” Tutorial App
So copied the “somescurity” project in Eclipse to a new ShiroFacebook project ( found I had to go to “project->properties->Web Project Settings” and change the context root).
Create a Facebook App
This requires you to have URL where the app will be deployed.
In Facebook https://developers.facebook.com/apps select development, and create an App.
First you need to come up with a display name and a namespace for the app.
Then in the Website “I want to allow people to log into my website using Facebook” section you need to provide the URL for your app.
You should then have an App ID, and an App Secret for your application – make a note of these.
Add Login Via Facebook Link
Next add a login via facebook link on index.jsp , which will be like this.
Where an “App ID” of 123456789012345 and the application will be running at http://www.somesite.co.uk/shirofb .
Create FacebookLogin Servlet
Now we need to create a FacebookLogin servlet to handle the redirection from Facebook.
I found this blog post very helpful:
http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/
So from Richard Nichol’s blog above and reading Facebook documentation I’ve ended with the follow servlet .
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.
<pre>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("fbAppSecret").toString(); private static final String APP_ID = props.get("fbAppId").toString(); private static final String REDIRECT_URL = props.get("fbLoginRedirectURL").toString(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("FacebookLoginServlet getting.."); FacebookUserDetails fud = authenticate(request, response); if (fud != null) { response.getWriter().write("<html><head/><body><h1>Facebook Logged In</h1><p>"+fud.toString()+"</p></body>"); response.getWriter().flush(); } else { try { System.out.println("fb log in failed"); String errorReason = request.getParameter("error_reason"); String error = request.getParameter("error"); response.getWriter().write("<html><head/><body><h1>fb login failed</h1>" + " reason:"+errorReason+" error:"+error+"</body>"); 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("Unexpected doPost ..."); } /** * 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("code"); if (code != null && code.trim().length() > 0) { URL authUrl = new URL("https://graph.facebook.com/oauth/access_token?" + "client_id=" + APP_ID + "&redirect_uri=" + REDIRECT_URL + "&client_secret=" + APP_SECRET + "&code=" + code); String authResponse = readURL(authUrl); System.out.println(authResponse); try { String accessToken = getPropsMap(authResponse).get("access_token"); URL url = new URL("https://graph.facebook.com/me?access_token=" + 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<String, String> getPropsMap(String someString) { String[] pairs = someString.split("&"); Map<String, String> props = new HashMap<String, String>(); for (String propPair : pairs) { String[] pair = propPair.split("="); 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 // { // "education": [{ // "school": { // "id": "123456789012345", // "name": "University of Sheffield" // }, // "type": "Graduate School", // "with": [{ // "id": "123456789", // "name": "Daffy Duck" // }] // }], // "first_name": "Mike", // "id": "121212121", // "last_name": "Warren", // "link": // "http://www.facebook.com/profile.php?id=121212121", // "locale": "en_US", // "name": "Mike Warren", // "updated_time": "2011-08-15T14:51:05+0000", // "verified": true // } private String jsonString; FacebookUserDetails(String fbResponse){ jsonString = fbResponse; } public String toString(){ return jsonString; } } }
… Next Part 2 Making use of Shiro
a Bruce Lee workout includes stretching, bending, running, dipping,
kicking, jumping, traditional muscle building exercises, weight lifting, rope skipping, medicine ball handling, etc.
Vitamin B3 or also called as Niacin is important in weight loss because it is responsible
for the regulation of thyroid hormones and also in sugar levels in
the body. Do not be tempted to lose weight as quickly as you can, because a crash diet will have you
eating less than a thousand calories a day slowing down your metabolism.
Traditional Japanese knife making requires at least 4 skilled craftsmen, and it takes them 2 weeks to complete a single blade.
The points actually protect the sharp inside curves that continue the cut, thus
the curves have less wear over time. With the right plastic surgeon, Los Angeles, you will be very happy with the results.
do you have entire source as a single package ? like may be in github
UnZa,).,'”,)).
LcPs..’,(“(),.
PEed’)),..”),(