2016-05-05 2 views
1

Наш проект состоит из приложения JavaFX, которое вызывает JEE-сервер по протоколу RMI. Мы используем сервер приложений Payara, вилку Glassfish. Мы хотим использовать JAAS с базой данных для управления аутентификацией и разрешениями, предоставляемыми пользователю.Jaas JDBC Authentication

Мы не понимаем, как связать созданную область JDBC с нашим приложением для взаимодействия с базой данных.

Можем ли мы программно вызывать область или напрямую запрашивать базу данных как here?

Служба запуска LoginContext:

@Stateless 
public class AuthenticationService implements IAuthenticationService { 
    @Override 
    public boolean login(User user) { 
     try { 
      LoginContext lc = new LoginContext(
       "JDBCLoginModule", 
       new JDBCCallbackHandler(user.getUsername(), user.getPassword()) 
      ); 

      lc.login(); 

      Subject subject = lc.getSubject(); 

      return true; 

     } catch (LoginException ex) { 
      ex.printStacktrace(); 
     } 
     return false; 
    } 
} 

LoginModule:

public class JDBCLoginModule implements LoginModule { 
    private Subject subject; 
    private CallbackHandler callbackHandler; 
    private Map sharedState; 
    private Map options; 

    private boolean succeeded = false; 

    @Override 
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { 
     this.subject   = subject; 
     this.callbackHandler = callbackHandler; 
     this.sharedState  = sharedState; 
     this.options   = options; 
     succeeded    = false; 
    } 

    @Override 
    public boolean login() throws LoginException { 
     if (callbackHandler == null) 
      throw new LoginException("The callbackHandler is null"); 

     Callback[] callbacks = new Callback[2]; 
     callbacks[0] = new NameCallback("name:"); 
     callbacks[1] = new PasswordCallback("password:", false); 

     try { 
      callbackHandler.handle(callbacks); 
     } catch (IOException e) { 
      throw new LoginException("IOException calling handle on callbackHandler"); 
     } 
     catch (UnsupportedCallbackException e) { 
      throw new LoginException("UnsupportedCallbackException calling handle on callbackHandler"); 
     } 

     NameCallback nameCallback   = (NameCallback) callbacks[0]; 
     PasswordCallback passwordCallback = (PasswordCallback) callbacks[1]; 

     String name = nameCallback.getName(); 
     String password = new String(passwordCallback.getPassword()); 

     // Call the JDBC Realm 
     /*if ("myName".equals(name) && "myPassword".equals(password)) { 
      succeeded = true; 
      return succeeded; 
     } 
     else { 
      succeeded = false; 
      throw new FailedLoginException("Sorry! No login for you."); 
     }*/ 
    } 

    @Override 
    public boolean commit() throws LoginException { 
     return succeeded; 
    } 

    @Override 
    public boolean abort() throws LoginException { 
     return false; 
    } 

    @Override 
    public boolean logout() throws LoginException { 
     return false; 
    } 
} 

CallbackHandler:

public class JDBCCallbackHandler implements CallbackHandler { 
    private final String username; 
    private final String password; 

    public JDBCCallbackHandler(String username, String password) { 
     this.username = username; 
     this.password = password; 
    } 

    @Override 
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { 
     for (int i = 0; i < callbacks.length; i++) { 
      if (callbacks[i] instanceof NameCallback) { 
       NameCallback nameCallback = (NameCallback) callbacks[i]; 
       nameCallback.setName(username); 
      } 
      else if (callbacks[i] instanceof PasswordCallback) { 
       PasswordCallback passwordCallback = (PasswordCallback) callbacks[i]; 
       passwordCallback.setPassword(password.toCharArray()); 
      } 
      else { 
       throw new UnsupportedCallbackException(callbacks[i], "The submitted Callback is unsupported"); 
      } 
     } 
    } 
} 

Мы создали JDBC область на сервере приложений: JDBC Realm Image

+0

Вы должны убедиться, что аутентификация JAAS работает с веб-приложения первого я думаю, потому что это удобный способ. – Supahupe

ответ

1

Если вы ожидали, что, позвонив по телефону AuthenticationService#login, вы будете авторизованы (аутентифицированы) для сервера Java EE (Payara), то это абсолютно неправильный подход.

После вызова lc.login(); сервер Java EE никоим образом не знает об этом вызове. Случайный LoginContext, который вы создаете с помощью нового оператора, не волшебным образом подключается к среде Java EE.

Если вы делаете удаленный вызов EJB, вам необходимо предоставить данные аутентификации с этим вызовом (из приложения JavaFx), а затем настроить аутентификацию для (удаленного) EJB в специальном способе GlassFish/Payara. В отличие от сервлетов, в Java EE нет стандартного способа аутентификации для EJB (для сервлетов вы используете JASPIC для этого).

Существует также нет такой вещи, как стандарт LoginModule. GlassFish использует интерфейс LoginModule, но в высоко подходит GlassFish. Если вы хотите использовать только область JDBC (область - это еще один термин для «хранилища идентификационных данных» здесь, что является еще одним термином для «модуля входа в систему»), вам нужно «настроить» это только с помощью стеклянной рыбы glassfish-ejb-jar. xml файл. К сожалению, почти никто не знает, как это сделать в точности, но я думаю, вам нужно посмотреть на ior-security-config и провести там исследования.

В качестве альтернативы вы можете использовать класс ProgrammaticLogin, который соответствует стандарту EJB GlassFish, эквивалентному стандарту HttpServletRequest#login.

См Java EE 6 Application Client login

Смежные вопросы