【问题标题】:Vaadin Authentication and AuhorizationVaadin 身份验证和授权
【发布时间】:2013-03-25 16:26:31
【问题描述】:

我是 Vaadin 的新手。 在此之前,我制作了一个 JSF Web 应用程序。 我有一个 ManagedBean 执行用户的登录。我使用了一个安全领域来委派凭据的实际验证。

如何在 Vaadin 中执行此操作?有最佳实践吗? 我正处于一个我会把一些东西放在一起的地步,但必须有某种标准程序,不是吗!? 我找到了一些关于此的教程,但主要使用 Spring(我想使用 EJB)。 此外,每个教程似乎都不必要的复杂。

对于如此常见的事情,必须有一些简单+结论性的教程。

【问题讨论】:

    标签: vaadin jaas


    【解决方案1】:

    这是我能找到的唯一一篇关于如何保护Vaadin aplication using JAAS 的 Vaadin 官方文章。我的意思是本地或官方 Vaadin 安全化。如果您使用 Spring security、Shiro 搜索一下,您会发现更多信息,但纯 ESB 使用 JAAS。 我同意这篇文章不足以学习如何设置应用程序。我在这里分享我的经验:

    1. Vaadin CDI 扩展:

    <!-- Vaadin Official DI support. -->
    <dependency>
      <groupId>com.vaadin</groupId>
      <artifactId>vaadin-cdi</artifactId>
      <version>1.0.0.alpha2</version>
    </dependency>
    

    2。了解 JAAS

    我建议您通过阅读概述文章来了解 JAAS 在非 vaadin 应用程序中是如何工作的,因为 JAAS 依赖于服务器应用程序提供者(TomEE、Jboss、Wildfly、Glasfish)都有不同的配置设置。 在这里,您将找到使用 Tomee 的proof of concept

    3。开发您自己的登录模块。

    如果您决定创建自定义登录模块,例如:

    public class MyLoginModule implements LoginModule {
    private CallbackHandler handler;
    private Subject subject;
    private UserPrincipal userPrincipal;
    private RolePrincipal rolePrincipal;
    private String login;
    private List<String> userGroups;
    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
    Map<String, ?> options) {
    handler = callbackHandler;
    this.subject = subject;
    }
    @Override
    public boolean login() throws LoginException {
    Callback[] callbacks = new Callback[2];
    callbacks[0] = new NameCallback("login");
    callbacks[1] = new PasswordCallback("password", true);
    try {
    handler.handle(callbacks);
    String name = ((NameCallback) callbacks[0]).getName();
    String password = String.valueOf(((PasswordCallback) callbacks[1]).getPassword());
    // Here we validate the credentials against some
    // authentication/authorization provider.
    // It can be a Database, an external LDAP, a Web Service, etc.
    // For this tutorial we are just checking if user is "user123" and
    // password is "pass123"
    if (name != null && name.equals("admin") && password != null && password.equals("admin")) {
    login = name;
    userGroups = new ArrayList<String>();
    userGroups.add("admin");
    return true;
    }
    // If credentials are NOT OK we throw a LoginException
    throw new LoginException("Authentication failed");
    } catch (IOException e) {
    throw new LoginException(e.getMessage());
    } catch (UnsupportedCallbackException e) {
    throw new LoginException(e.getMessage());
    }
    }
    @Override
    public boolean commit() throws LoginException {
    userPrincipal = new UserPrincipal(login);
    subject.getPrincipals().add(userPrincipal);
    if (userGroups != null && userGroups.size() > 0) {
    for (String groupName : userGroups) {
    rolePrincipal = new RolePrincipal(groupName);
    subject.getPrincipals().add(rolePrincipal);
    }
    }
    return true;
    }
    @Override
    public boolean abort() throws LoginException {
    return false;
    }
    @Override
    public boolean logout() throws LoginException {
    subject.getPrincipals().remove(userPrincipal);
    subject.getPrincipals().remove(rolePrincipal);
    return true;
    }
    }
    

    在应用程序的 META-INF/context.xml 中引用它。此设置适用于 TomEE,但对于 glashfish 或其他必须类似。

    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
      <Realm className="org.apache.catalina.realm.JAASRealm" appName="myrealm" userClassNames="net.sf.jaas.auth.UserPrincipal"
        roleClassNames="net.sf.jaas.auth.RolePrincipal" />
    </Context>
    

    注意 userClassNames 和 roleClassNames 只是简单的 Java Pojo,但必须实现 java.security.Principal;

    3。在您的 Vaadin 登录视图中启用 JAAS

    使用 Vaadin TextField 和 Password 定义您最喜欢的登录表单,并在您的 doLoginEvent() 中定义对 JAAS 的引用。 每当调用 JaasAccessControl.login 时,都会创建一个新的 LoginModule 实例。

      import com.vaadin.cdi.access.JaasAccessControl;
      try {
                JaasAccessControl.login(loginEvent.getUsername(), loginEvent.getPassword());
                logger.info("User {} authenticated", getPrincipalName());
                navigator.navigateTo(Main.NAME);
            } catch (Exception e) {
                Notification.show("Error logging in", Type.ERROR_MESSAGE);
                logger.error(e.getMessage(), e);
            }
    

    4.使用您登录用户的信息。

    每当用户通过 JAAS 登录过滤器时。它将在他的请求上下文中提供一个标识他的类。这个类叫做 Principal(你之前在 LoginModule 类中设置的那个)。

    public boolean isUserInRole(String role) {
            return JaasAccessControl.getCurrentRequest().isUserInRole(role);
        }
    
        public String getPrincipalName() {
            Principal principal = JaasAccessControl.getCurrentRequest().getUserPrincipal();
            if (principal != null) {
                return principal.getName();
            }
    
            return null;
        }
    
        public boolean isUserSignedIn() {
            Principal principal = JaasAccessControl.getCurrentRequest().getUserPrincipal();
            return principal != null;
        }
    

    5. LoginModule 的替代品

    创建您的自定义登录模块不是强制性的,通常 Java EE 提供商作为 Tomee 提供很少的实现。在某些数据库表中,基于属性文件的身份验证。 查看Tomee documentation JAAS 以查看一些示例:

    6.在 TomEE 中启用 JAAS 您需要创建一个引用您 LoginModule 的 jaas.config 文件,例如:

    filename: jaas.config 
    myrealm{
        net.sf.jaas.MyLoginModule required;
    };
    

    然后用这个参数启动应用服务器:

    -Djava.security.auth.login.config=E:/apache-tomee-jaxrs-1.6.0.2/conf/jaas.config
    

    如果你想看看这个概念的证明。 Checkout this example,使用 Tomee、Vaadin 7、JAAS,

    【讨论】:

      【解决方案2】:

      几个月前我遇到了同样的问题。当时我无法弄清楚它是如何工作的,所以我查看了 spring 插件,现在我正在使用 Vaadin 登录表单和 spring security

      【讨论】:

      • 非常感谢您的回答。不过我会留下这个问题,因为有人可能会想出一个纯 Vaadin 解决方案。
      【解决方案3】:

      使用 JAAS、Vaadin 8、Vaadin CDI 插件和内置LoginForm 的完整示例可用here,步骤如下:

      1. pom.xml 中启用 Vaadin CDI 插件
      2. 使用@CDIUI 注解启用CDI in Vaadin UI 并配置Navigator
      3. 通过添加@RolesAllowed 注释(或任何其他javax.annotation.security 注释)启用authorization in a CDI view
      4. 实现派生自内置LoginForma login view,并使用JaasAccessControl 对用户进行身份验证。

      一旦你弄清楚这些部分是如何组合在一起的,这实际上是一种相当不错、流畅的体验。

      Vaadin wiki 中有一篇较长的文章解释了如何将数据库支持的身份验证与 JAAS 一起使用。

      【讨论】:

        猜你喜欢
        • 2010-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-27
        • 2014-11-13
        • 2014-12-27
        • 1970-01-01
        相关资源
        最近更新 更多