(Quick Reference)
Vkontakte Authentication for Spring Security - Reference Documentation
Authors: Pavel Burov
Version: 1.0
1 Introduction
Grails plugin for Vkontakte Authentication, as extension to Grails Spring Security Core plugin.
Requirements:
- grails 2.0+
- spring-security-core plugin 2.0-RC2
- jquery (for Open API authorization)
Links:
2 Installation
Add dependency into
BuildConfig.groovy
:
plugins {
compile "org.grails.plugins:spring-security-vkontakte:1.0"
// …
// you need to have spring-security-core plugin installed
// …
}
Call (optionaly) configuration wizards by:
grails s2-quickstart //configure Spring Security Core
grails s2-init-vkontakte //configure Spring Security Vkontakte
Or you can edit
Config.groovy
instead and put your Vkontakte App appId/secret and domain class configuration into
Config.groovy
:
grails.plugin.springsecurity.vkontakte.appId = ..
grails.plugin.springsecurity.vkontakte.secret = ..
grails.plugin.springsecurity.vkontakte.domain.className = 'com.company.VkontakteUser'
It's very basic configuration, for other options (see
Configuration section)
Follow
Basic Usage guide for full example.
3 Usage
Example app
You can take a look at
Example Application, it's very
basic app, that shows how to use the plugin. Just clone it, put your Vkontakte App credentials, and play with the code.
Usage
Setup Vkontakte credentials
Put your Vkontakte App appId/secret into
Config.groovy
:
grails.plugin.springsecurity.vkontakte.appId = ..
grails.plugin.springsecurity.vkontakte.secret = ..
Create domain class for your user
Like
domain/VkontakteUser.groovy
:
class VkontakteUser {
Long vkId
String accessToken
Date accessTokenExpires static belongsTo = [user: User] // connected to main Spring Security domain static constraints = {
vkId unique: true
}
}
The plugin is configured for
VkontakteUser
class name by default. But you could use different name (or use package) for domain class,
for example
com.company.UserWithVkontakte
, that you should configure at
Config.groovy
at this case:
grails.plugin.springsecurity.vkontakte.domain.className = 'com.company.VkontakteUser'
Put SignIn with Vkontakte button:
Add into your GSP:
<vkontakteAuth:connect />
Use Spring Security
Now you could use all security tools provided by
Spring Security Core.
For example, you could use taglib for checking user state:
<sec:ifLoggedIn>
<div class="message">Authenticated</div>
Hello <sec:username/>!
</sec:ifLoggedIn><sec:ifNotLoggedIn>
<div class="message">Not authenticated</div>
<vkontakteAuth:connect />
</sec:ifNotLoggedIn>
4 Configuration
Basic Configuration
Make sure that you have installed and configured spring-security-core plugin before this step.
Calling 'grails s2-init-vkontakte' will make default configuration of plugin for you, make sure that you have configuration in your
Config.groovy
like:
grails.plugin.springsecurity.vkontakte.domain.className = '<your VkontakteUser domain>'
grails.plugin.springsecurity.vkontakte.appId = '<Vkontakte appId>'
grails.plugin.springsecurity.vkontakte.secret = '<Vkontakte secret>'
Or you can skip 'grails s2-init-vkontakte' step, and make such configuration by yourself.
When you have valid configuration you can put Vkontakte Connect button in you GSP:
<vkontakteAuth:connect />
Vkontakte configuration
Name | Default Value |
---|
grails.plugin.springsecurity.vkontakte.appId | must be specified |
grails.plugin.springsecurity.vkontakte.secret | must be specified |
Permissions
Name | Default Value |
---|
grails.plugin.springsecurity.vkontakte.permissions | |
See:
Vkontakte App permissionsDomain configuration
Name | Default Value |
---|
grails.plugin.springsecurity.vkontakte.domain.className | VkontakteUser |
grails.plugin.springsecurity.vkontakte.domain.userConnectionPropertyName | user |
grails.plugin.springsecurity.vkontakte.domain.userIdPropertyName | vkId |
Where:
.classname
- domain class name that will be used for authentication
.connectionPropertyName
- name of property that connects (belongsTo) to main app user (if you have two different domains, one for app user, one for Vkontakte user)
.userIdPropertyName
- name of property to hold Vkontakte user id
Authentication configuration
Name | Default Value |
---|
grails.plugin.springsecurity.vkontakte.autoCreate.enabled | true |
grails.plugin.springsecurity.vkontakte.autoCreate.roles | 'ROLE_USER', 'ROLE_VKONTAKTE' |
Where:
.autoCreate.enabled
- plugin will automatically create corresponding user for each new visitor authentication using Vkontakte
.autoCreate.roles
- default list of roles that will be assigned to create user
Filters configuration
Redirect
Name | Default Value |
---|
grails.plugin.springsecurity.vkontakte.filters.redirect.processUrl | '/j_spring_security_vkontakte_check' |
grails.plugin.springsecurity.vkontakte.filters.redirect.position | SecurityFilterPosition.OPENID_FILTER.order + 1 |
grails.plugin.springsecurity.vkontakte.filters.redirect.authenticationSuccessHandler | '' |
grails.plugin.springsecurity.vkontakte.filters.redirect.authenticationFailureHandler | '' |
grails.plugin.springsecurity.vkontakte.filters.redirect.successHandler | {} |
grails.plugin.springsecurity.vkontakte.filters.redirect.failureHandler | {} |
Where:
.filters.redirect.processUrl
- url that will be used for authentication
.filters.redirect.position
- filter position
.filters.redirect.authenticationSuccessHandler
- bean name to use as authentication successHandler
.filters.redirect.authenticationFailureHandler
- bean name to use as authentication FailureHandler
.filters.redirect.successHandler
- configuration for predefined handler
.filters.redirect.failureHandler
- configuration for predefined handler
Open API
Name | Default Value |
---|
grails.plugin.springsecurity.vkontakte.filters.openApi.processUrl | '/j_spring_security_vkontakte_open_api_check' |
grails.plugin.springsecurity.vkontakte.filters.openApi.position | SecurityFilterPosition.OPENID_FILTER.order + 2 |
grails.plugin.springsecurity.vkontakte.filters.openApi.authenticationSuccessHandler | '' |
grails.plugin.springsecurity.vkontakte.filters.openApi.authenticationFailureHandler | '' |
Where:
.filters.openApi.processUrl
- url that will be used for authentication
.filters.openApi.position
- filter position
.filters.openApi.authenticationSuccessHandler
- bean name to use as authentication successHandler
.filters.openApi.authenticationFailureHandler
- bean name to use as authentication FailureHandler
5 Using VkontakteAuthService
How it works
If you want to add some specific logic to default plugin behaviour, you have to create your own
service called 'vkontakteAuthService'. Then the plugin will check for known methods of this service, and if
they're exist - use them instead of or in additional to own method.
It's some kind of extending an abstract class, but you don't need to create all methods, just what you need.
Used objects:
<VkontakteUser>
- domain class for your vkontakte user. It's your own class, can have other name, it's just a example
<Person>
- general user, used by Spring Security. It's your own class, can have other name, it's just a example
VkontakteAuthToken
- token provided by plugin (instance of com.burig.grails.springsecurity.vkontakte.VkontakteAuthToken
)
VkontakteAuthToken contains:
- String code
- VkontakteAccessToken accessToken
- Long userId
- String accessToken
- Date expireAt
Notice that
<VkontakteUser>
and
<Person>
can be same object, or can be two different object (with a relation), depends
on your architecture.
Take a look at sources
To understand how it works, and which methods you can use for customization.
Take a look at sources of
DefaultVkontakteAuthDaoList of possible methods:
<VkontakteUser>
findUser(VkontakteAuthToken token)
Called when vkontakte user is authenticated (on every request), must return existing instance
for specified token, if exits. If doesn't - return
null
.
<VkontakteUser>
create(VkontakteAuthToken token)
Called when we have a new vkontakte user, called on first login to create all required data structures.
Notice, that if you have such method, it replaces all other methods for user creation, like:
- createAppUser
- prepopulateAppUser
- onCreate
- afterCreate
- createRoles
<Person>
createAppUser(<VkontakteUser>
user, VkontakteAuthToken token)
Called if you have configured two domains, one for main user, one for vkontakte user.
void afterCreate(<VkontakteUser>
user, VkontakteAuthToken token)
Called after user was created by plugin, just after saving into database, but before roles are assigned to user.
You can setup user object with some extra values. If you need to access Vkontakte API, you could use token, it
contains 'accessToken' for current user.
void createRoles(<VkontakteUser>
user)
Called when we have a new Vkontakte user, called on first login to create roles list for new user. If method doesn't exist,
user will be created with default roles (configured at 'grails.plugins.springsecurity.vkontakte.autoCreate.roles')
void updateToken(<VkontakteUser>
user, VkontakteAuthToken token)
Called on each login, you could update user details if needed.
<Person>
getAppUser(<VkontakteUser>
user)
Must return object to store in security context for specified vkontakte user (can return itself)
Object getPrincipal(<Person>
person)
Principal to use with Spring Security. It's very useful if it will be instance of
UserDetails
class.
Collection<GrantedAuthority> getRoles(<Person>
user)
Must return roles list for specified vkontakte user
6 Common Issues
Enable logging
If you have troubles with plugin, please enabled logging, so you can see what's happening:
log4j = {
debug 'com.burig'
}
Authentication don't work with localhost
domain
Make sure that you're using a real domain name for your application. Not a
localhost
, and avoid
.local
domains as well.
You can make a fake domain like
dev.myapp.com
, by putting into
/etc/hosts
the following line:
If you already have line starting with
127.0.0.1
, just add your
dev.myapp.com
at the end of the line.
See more details about hosts file, and location of the file for different operation systems see:
hosts (file)After that, you should configure your Grails app to use this domain, by adding following line into
Config.groovy
.
Of course, you need to use this domain only for development, so put this configuration into
development
environment config:
environments {
development {
grails.serverURL = "http://dev.myapp.com:${System.getProperty('server.port', '8080')}/${appName}"
}
}