3 Usage - Reference Documentation
Authors: Igor Artamonov (igor@artamonov.ru)
Version: 0.17
Table of Contents
3 Usage
3.1 Basic Usage
Example app
You can take a look at Example Application, it's very basic app, that have only one page, with 'Facebook Connect' button. Just clone it, put your FB App credentials, and play with it.How to add Facebook Authentication into your existing application
Initial plugin config
Domain Class
Create domain class for your facebook user:class FacebookUser { Long uid String accessToken Date accessTokenExpires static belongsTo = [user: User] //connected to main Spring Security domain static constraints = { uid unique: true } }
Config.groovy
setup full name (including package name, if used) of just created Facebook user domain, like:grails.plugin.springsecurity.facebook.domain.classname='FacebookUser'
Add FB App credentials
You should create a Facebook App and copy App ID and Secret:intoConfig.groovy
:
grails.plugin.springsecurity.facebook.appId=12345678900000 grails.plugin.springsecurity.facebook.secret=76c2279743c99da3715e3d00f29a1234
Add Facebook Connect button
There is special taglib (<facebookAuth:
) that can be used at your view (any GSP page) to add Facebook Connect button.Following code displays connect button for not authorized user, or show a welcome message to logged in user:
<sec:ifNotGranted roles="ROLE_USER"> <facebookAuth:connect /> </sec:ifNotGranted> <sec:ifAllGranted roles="ROLE_USER"> Welcome <sec:username/>! (<g:link uri="/j_spring_security_logout">Logout</g:link>) </sec:ifAllGranted>
Run
That's it! Run your application, and test that everything is working.3.2 Filters
How it works
Plugin is based on Spring Security and uses web filters for authorization, for more details see Spring Security docsAvailable filters
There are 4 types of filter:- FacebookAuthRedirectFilter - server-side authorization (used by default)
- FacebookAuthCookieTransparentFilter - automatic client-side authorization
- FacebookAuthCookieDirectFilter - manual client-side authorization
- FacebookAuthJsonFilter - for external clients (like Android/iOS app)
Server-Side authentication (FacebookAuthRedirectFilter)
It's a standard Login for Server-side Apps. After clicking on 'connect button' user gets redirected to special Facebook page, for authentication, and then redirected back to your app.Client-Side authentication
Transparent cookie based authorization (FacebookAuthCookieTransparentFilter)
Based on Facebook Javascript SDK authorization. On client side it makes Facebook authorization and put Facebook Cookie (it's made by Facebook Javascript, you don't need anything special)After successful authorization on client side, the browser should reload current page. Or open any other page.This filter will process each request, and if it sees valid Facebook cookie, it makes authorization for current user. If it's a new user, it creates a new one for application, with provided Facebook credentials.It's per-request authorization. That means that this filter will try to authorize user on each page request.
Manual cookie based authentication (FacebookAuthCookieDirectFilter)
Based on Facebook Javascript SDK authorization. On client side it makes Facebook authorization and put Facebook Cookie (it's made by Facebook Javascript, you don't need anything special)Same as FacebookAuthCookieTransparentFilter, it parse Facebook cookie, but only for specified url. Like username/password filter from spring-security-core or similar. After successful authorization it can redirect user to specified url.JSON or Android/iOS/desktop authorization (FacebookAuthJsonFilter)
Client should send Access Token or Signed Request as parameter, and will get JSON response with user details.See filter docsFilter configuration
You can use config parametergrails.plugin.springsecurity.facebook.filter.type
to configure which filters
you want to use in your application.It's not a Spring Security configuration, not a configuration for Spring filters. Just a extra configuration, that used only by this plugin.By default it uses only one 'redirect' filter:
grails.plugin.springsecurity.facebook.filter.type='redirect'
grails.plugin.springsecurity.facebook.filter.type='transparent,cookieDirect'
redirect
- use standard server side authorizationtransparent
- use transparent cookie based authorizationcookieDirect
- use manual cookie based authorizationjson
- use JSON authorization
3.3 Server Side Authentication
It's the `FacebookAuthRedirectFilter`, enabled by default.It's preferred and a standard Login for Server-side Apps. After clicking on 'connect button' user gets redirected to special Facebook page, for authentication, and then redirected back to your app.User going to see Facebook Authentication screen only at the first time. Next time user will be redirected back from Facebook to your application immediately.
How to process failed login
When user declines Facebook Authentication (click Cancel, for example), you'll '401 Authentication Failed' by default. It's default configuration of Spring Security failure handler, but for most cases it's not what you really want.To handle this situation you have to create your own Failure Handler, a bean implementingorg.springframework.security.web.authentication.AuthenticationFailureHandler
. If you just need to
show a page (a GSP view), you can use standard SimpleUrlAuthenticationFailureHandler
, that could redirect
failed authentication to specified URL.For example you can create bean at resources.groovy
:import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler// Place your Spring DSL code here beans = { redirectFailureHandlerExample(SimpleUrlAuthenticationFailureHandler) { defaultFailureUrl = '/failed' //redirect to this URL when authentication fails }}
Config.groovy
:grails.plugin.springsecurity.facebook.filter.redirect.failureHandler='redirectFailureHandlerExample'
3.4 Client Side Authentication
Based on Facebook Javascript SDK authorization. Useful when you need to use FB Javascript SDK on client side.And there are two ways:- try authenticate user on each request, to any page - it's
transparent
filter - authenticate only when user redirected to specified page, like a standard username/password authentication - it's
cookieDirect
filter
Transparent filter
If you're using first way (transparent
filter), your user will be automatically authenticated whenever he has
Facebook cookie. Btw, don't forget that you should reload current page after you have successfully authenticated user
on client side. Like:<facebookAuth:init> FB.Event.subscribe('auth.login', function() { window.location.reload(); }); </facebookAuth:init>
FB.logout()
(using Javascript) on client side.CookieDirect filter
If you're using second way (cookieDirect
filter), you could configure URL that will be used for authentication at Config.groovy
:grails.plugin.springsecurity.facebook.filter.processUrl = '/j_spring_security_facebook_check' //it's default value
<facebookAuth:init> FB.Event.subscribe('auth.login', function() { window.location.href = '/j_spring_security_facebook_check' }); </facebookAuth:init><g:javascript> $('#fbloginbutton').click(function() { FB.login(); }); </g:javascript>
3.5 Json Authentication
Filter 'FacebookAuthJsonFilter' accepts Facebook Access Token or Signed Request as parameter, and responds with JSON to authorization requests. It's useful if you an external client for your Grails application, it could be Android or iOS application, or Desktop application, or just AJAX client.JSON filter just returns an object with user details, nothing else. For authentication of other requests, you still have to use different filter. If you have a RESTful client, take a look at spring-security-oauth2-provider pluginHow it works:
> GET /j_spring_security_facebook_json?access_token=<ACCESS_TOKEN>
< HTTP/1.1 200 OK < Content-Type: application/json;charset=UTF-8 < { "authenticated": true, "uid": 12345612345, # Facebook User Id "roles":[ "ROLE_FACEBOOK", "ROLE_USER" ], "username": "facebook_12345612345", # Grails Application User Id/Username "enabled": true # Grails Application User status }
< HTTP/1.1 401 Unauthorized < Content-Type: application/json;charset=UTF-8 < { "authenticated": false, "message": "Expired token" # Authentication Failure reason }
How to extend JSON response
The plugin going to callMap onJsonSuccess(Map input, FacebookAuthToken token)
or Map onJsonFailure(Map input, AuthenticationException exception)
methods
of FacebookAuthService (if exists).There you can update input
data with any other values, introduce new fields/keys, or even return your
own structure. This structure will be transformed to JSON and sent to client.