Frage

I am using Play 2.0.4 with SecureSocial. I would like to use a UsernamePasswordProvider to persist user registrations to a database.

I am relatively new to Java and the Play Framework so I'm not really sure how to get this done. I got as far as creating a simple model called 'User' but don't know how to go further from here.

I hope that there's somebody out there who might be able to help me and I'm sure this has been done before. Thanks very much in advance!

@Entity
public class User extends Model {
  //
}
War es hilfreich?

Lösung

assuming you have Play2.0 configured for using SecureSocial, you can start from this question: Play SecureSocial Persistance with Java I've managed to make that work with some minor corrections:

You need some local representation of your users to take care of storing user info to your persistence layer. I used Ebean and a simple LocalBean. Something like this will do it:

package models;

import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import play.db.ebean.Model;
import play.data.validation.*;
import play.data.format.*;

@Entity
public class LocalUser extends Model {

    @Id
    public String id;
    public String name;
    public String email;
    public String password;
    public String provider;
        public String firstName;
        public String lastName;

        public static Finder<String, LocalUser> find = new Finder<String, LocalUser (String.class,LocalUser.class);


/**
 * Retrieve a User using an email.
 */
    public static LocalUser findByEmail(String email) {
        return find.where().eq("email", email).findUnique();
    }
}

For my Token class I used the same as the one proposed in the mentioned question:

package models;

import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import play.db.ebean.Model;

@Entity
public class LocalToken extends Model {

    private static final long serialVersionUID = 1L;

    @Id
    public String uuid;
    public String email;
    public Date createdAt;
    public Date expireAt;
    public boolean isSignUp;
    public static Finder<String, LocalToken> find = new Finder<String, LocalToken>(
        String.class, LocalToken.class
    );
}

For the UserService, I had to make some minor corrections to the mentioned question, to make it work on the newer version of SecureSocial, in which the user().id property was replaced by identityId():

package services;


import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.joda.time.DateTime;

import models.LocalToken;
import models.LocalUser;
import play.Application;
import play.Logger;
import scala.Option;
import scala.Some;
import securesocial.core.AuthenticationMethod;
import securesocial.core.Identity;
import securesocial.core.PasswordInfo;
import securesocial.core.SocialUser;
import securesocial.core.IdentityId;
import securesocial.core.java.BaseUserService;
import securesocial.core.java.Token;

public class SqlUserService extends BaseUserService {

    public SqlUserService(Application application) {
        super(application);
    }

    @Override
    public void doDeleteExpiredTokens() {
        if (Logger.isDebugEnabled()) {
            Logger.debug("deleteExpiredTokens...");
        }
        List<LocalToken> list = LocalToken.find.where().lt("expireAt", new DateTime().toString()).findList();
        for(LocalToken localToken : list) {
            localToken.delete();
        }
    }

    @Override
    public void doDeleteToken(String uuid) {
        if (Logger.isDebugEnabled()) {
            Logger.debug("deleteToken...");
            Logger.debug(String.format("uuid = %s", uuid));
        }
        LocalToken localToken = LocalToken.find.byId(uuid);
        if(localToken != null) {
            localToken.delete();
        }
    }

    @Override
    //public Identity doFind(UserId userId) {
    public Identity doFind(IdentityId identityId){
        if (Logger.isDebugEnabled()) {
            Logger.debug(String.format("finding by Id = %s", identityId.userId()));

        }
        LocalUser localUser = LocalUser.findByEmail(identityId.userId());
        if(localUser == null) return null;
        SocialUser socialUser = new SocialUser(new IdentityId(localUser.id, localUser.provider),    
            localUser.firstName, 
            localUser.lastName, 
            String.format("%s %s", localUser.firstName, localUser.lastName),
            Option.apply(localUser.email), 
            null, 
            new AuthenticationMethod("userPassword"),
            null, 
            null, 
            Some.apply(new PasswordInfo("bcrypt", localUser.password, null))
        );  
        if (Logger.isDebugEnabled()) {
            Logger.debug(String.format("socialUser = %s", socialUser));
        }
        return socialUser;
    }


    @Override
    public Identity doFindByEmailAndProvider(String email, String providerId) {
        List<LocalUser> list = LocalUser.find.where().eq("email", email).eq("provider", providerId).findList();
        if(list.size() != 1){
            Logger.debug("found a null in findByEmailAndProvider...");
            return null;
        }
        LocalUser localUser = list.get(0);
        SocialUser socialUser = 
                new SocialUser(new IdentityId(localUser.email, localUser.provider),
                        localUser.firstName, 
                        localUser.lastName, 
                        String.format("%s %s", localUser.firstName, localUser.lastName),
                        Option.apply(localUser.email), 
                        null, 
                        new AuthenticationMethod("userPassword"),
                        null, 
                        null, 
                        Some.apply(new PasswordInfo("bcrypt", localUser.password, null))
                   );  
        return socialUser;
    }

    @Override
    public Token doFindToken(String token) {
        if (Logger.isDebugEnabled()) {
            Logger.debug("findToken...");
            Logger.debug(String.format("token = %s", token));
        }
        LocalToken localToken = LocalToken.find.byId(token);
        if(localToken == null) return null;
        Token result = new Token();
        result.uuid = localToken.uuid;
        result.creationTime = new DateTime(localToken.createdAt);
        result.email = localToken.email;
        result.expirationTime = new DateTime(localToken.expireAt);
        result.isSignUp = localToken.isSignUp;
        if (Logger.isDebugEnabled()) {
            Logger.debug(String.format("foundToken = %s", result));
        }
        return result;
    }

    @Override
    public Identity doSave(Identity user) {
        if (Logger.isDebugEnabled()) {
            Logger.debug("save...");
            Logger.debug(String.format("user = %s", user));
        }
        LocalUser localUser = null;
        //localUser = LocalUser.find.byId(user.id().id());
        localUser = LocalUser.find.byId(user.identityId().userId());

        if (localUser == null) {
            Logger.debug("adding new...");
            localUser = new LocalUser();
            //here was localUser.id = user.id().id();
            localUser.id = user.identityId().userId();
            localUser.provider = user.identityId().providerId();
            localUser.firstName = user.firstName();
            localUser.lastName = user.lastName();
            localUser.email = user.email().get();
            localUser.password = user.passwordInfo().get().password();
            localUser.save();
        } else {
            Logger.debug("existing one...");
            localUser.id = user.identityId().userId();
            localUser.provider = user.identityId().providerId();
            localUser.firstName = user.firstName();
            localUser.lastName = user.lastName();
            localUser.email = user.email().get();
            localUser.password = user.passwordInfo().get().password();
            localUser.update();
        }
        return user;
    }

    @Override
    public void doSave(Token token) {
        LocalToken localToken = new LocalToken();
        localToken.uuid = token.uuid;
        localToken.email = token.email;
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            localToken.createdAt = df.parse(token.creationTime.toString("yyyy-MM-dd HH:mm:ss"));
            localToken.expireAt = df.parse(token.expirationTime.toString("yyyy-MM-dd HH:mm:ss"));
        } catch (ParseException e) {
            Logger.error("SqlUserService.doSave(): ", e);
        }
        localToken.isSignUp = token.isSignUp;
        localToken.save();
    }
}

That's it. Please note that passwords are stored hashed using Bcrypt, so you need to hash you passwords for it to work. The easiest way to get your hashed pass is simple to use the registration process provided by SecureSocial.

Hope this helps.

L.

Andere Tipps

You need to implement a subclass of UserService and register that plugin in the play.plugins file so that SecureSocial picks it up. From your UserService implementation you will use your model class to save/find the information.

There's a pull request with a sample UserService (in Scala though) you can use as a guide: https://github.com/jaliss/securesocial/pull/163.

You can also use the InMemoryUserService in the samples as a starting point and replace the hash maps it uses with calls to your model object to persist/retrieve things.

In the pull request above, what is the purpose of the AuthenticatorStore file?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top