Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could AAA support multiple login types dynamically #15

Open
leeaee opened this issue Sep 1, 2017 · 0 comments
Open

Could AAA support multiple login types dynamically #15

leeaee opened this issue Sep 1, 2017 · 0 comments

Comments

@leeaee
Copy link

leeaee commented Sep 1, 2017

Background
In some scenario, we need to support user login with multiple types, such as login by register username, register mobile or some third party SSO account.

Currently
You could define which field need AAA checked for login by overriding the method protected String userKey(). But once you fixed the value, AAA could not change the checking field.

For example:
I have a user in my database as follow, and I want to support user could log in with login_name, mobile, and email.
User of database

  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'PK',
  `login_name` VARCHAR(63) NULL COMMENT 'login name',
  `mobile` VARCHAR(31) NULL COMMENT 'login mobile',
  `email` VARCHAR(127) NULL COMMENT 'login email',
  `password` VARCHAR(63) NOT NULL COMMENT 'password in sha1',
  `salt` VARCHAR(31) NOT NULL COMMENT 'salt for password',
  `state` VARCHAR(31) NOT NULL DEFAULT '' COMMENT 'user state',

User entity

@DB()
@Entity
@Table(name = "bb_user")
public class User implements SimpleBean {

    public Long id;

    @Column(name = "login_name", updatable = false)
    public String loginName;

    public String mobile;

    public String email;

    public String password;

    public String salt;

    public String state;
}

Currently, in AAA framework, we could only bind a fixed field. It means we could only support the type of loginName to log in.

public class SecurityService extends ActAAAService.Base<User> {

    public static final int HASH_INTERATIONS = 1024;
    public static final int SALT_SIZE = 8;
    private static final String USER_KEY = "loginName";

    @Override
    protected String userKey() {
        return USER_KEY;
    }
}

If you want to change the login type, you need to modify the USER_KEY. But this could not change dynamically.
And there another issue, we could not get the login type from login request to AAA.

Workaround
Here I have a workaround for this kind of situation.

  1. Define a loginType class for the field.
public enum LoginType {

    NAME("loginName"),
    MOBILE("mobile"),
    EMAIL("email");

    private String field;

    LoginType(String field) {
        this.field = field;
    }

    public String getField() {
        return field;
    }
}
  1. Add the login type in login request as fomart: identifier:login-type:login-value
{
    "identifier":"MOBILE:13881882856",
    "password":"111111"
}
  1. Parse login type and login value for login method.
    @PostAction("login")
    @ResponseStatus(200)
    public void login(String identifier, String password, ActionContext context) {
        User user = authenticate(identifier, password);
        unauthorizedIf(null == user);
        context.login(identifier);
    }

    private User authenticate(String identifier, String password) {
        String[] keyValue = identifier.split(SecurityService.SPILT_CHAR);
        User user = dao.findOneBy(LoginType.valueOf(keyValue[0]).getField(), keyValue[1]);
        if (null == user || !isMatchedPassword(user, password)) return null;
        return user;
    }
  1. Overriding findByName in AAA service and also parse the login type and login value from the session username.
    public static final String SPILT_CHAR = ":";

    @Override
    public Principal findByName(String name) {
        String[] keyValue = name.split(SPILT_CHAR);
        User user = dao.findOneBy(LoginType.valueOf(keyValue[0]).getField(), keyValue[1]);
        return null == user ? null : principalOf(user);
    }

@greenlaw110 do you have any other better solution, or could you plan enhancement AAA to support this kind of requirement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant