Seam使用凭据自动登录

时间:2009-10-08 19:45:27

标签: java jsf jboss seam

我成功创建了一个使用seam凭证进行身份验证的项目,但是现在一些要求已经改变(像往常一样),我需要自动验证用户身份。见下面的例子:

用户致电页面:http://server:port/project/index.jsp?parameter=xyz。此页面必须调用seam组件并获取参数以填充credentials.username,但它不能按预期工作。

my pages.xml:

<page view-id="*" action="#{authenticator.authenticate}" >
    <rewrite pattern="/index/{cpf}" />
    <rewrite pattern="/home/{cpf}" />
    <param name="#{credentials.username}" value="123456" />
    <param name="authenticator.teste" value="#{param['cpf']}" />
    <param name="cpf" value="#{param['cpf']}" />
    <param name="token" value="#{param['cpf']}" />
    <navigation >
        <rule if-outcome="home">
            <redirect view-id="/home.xhtml" />
        </rule>
        <rule if-outcome="index">
            <redirect view-id="#{authenticator.authenticate}" include-page-params="true" />
        </rule>
    </navigation>
</page>

我的authenticatorBean(这里有很多测试,我尝试了一切):

@Stateless
@Name("authenticator")
public class AuthenticatorBean implements Authenticator {

    @Out String token;
    @Out String cpf;
    @Out String xyz;
    @Out String teste;

    @Logger private Log log;
    @In EntityManager entityManager;
    @In Identity identity;
    @In Credentials credentials;
    public boolean authenticate() {

        System.out.println(credentials.getUsername());

        System.out.println(cpf);
        System.out.println(xyz);
        System.out.println(teste);


        @SuppressWarnings("unused")
        FacesContext fcx = FacesContext.getCurrentInstance();
        String cpf = fcx.getExternalContext().getRequestContextPath();
        String cpf2 = fcx.getExternalContext().getRequestParameterMap().get("token");
        String cpf21 = fcx.getExternalContext().getRequestParameterMap().get("cpf");
        String cpf22 = fcx.getExternalContext().getRequestParameterMap().get("xyz");
        String cpf23 = fcx.getExternalContext().getRequestParameterMap().get("teste");
        String cpf3 = fcx.getExternalContext().getInitParameter("cpf");
        String cpf4 = fcx.getExternalContext().getRequestPathInfo();
        String cpf5 = fcx.getExternalContext().getRequestServletPath();
        Object cpf6 = fcx.getExternalContext().getRequest();
        Object cpf7 = fcx.getExternalContext().getContext();
        Object cpf8 = fcx.getExternalContext().getRequestMap();
        Object cpf9 = fcx.getExternalContext().getRequestParameterNames();

        log.info("authenticating {0}", credentials.getUsername());
        Usuario usuario = (Usuario) entityManager.createQuery("select u from Usuario u where u.cpf = :cpf")
        .setParameter("cpf", credentials.getUsername())
        .getSingleResult();

        log.info("authenticating {0}", credentials.getUsername());

        if (usuario != null) {
             identity.addRole("admin");
             return Boolean.TRUE;
        }

        return false;
    }

}
有人能帮帮我吗?我无法在authenticatorBean中获取参数

谢谢!

3 个答案:

答案 0 :(得分:2)

很简单。见下文:

pages.xml中

<page view-id="/home.xhtml">
        <action execute="#{identity.login}" if="#{not identity.loggedIn}" />
        <param name="username" />
        <navigation from-action="#{identity.login}">
            <rule if="#{identity.loggedIn}">
                <redirect view-id="/home.xhtml"/>
            </rule>
            <rule if="#{not identity.loggedIn}">
                <redirect view-id="/error.xhtml"/>
            </rule>
        </navigation>
    </page>

如您所见,我声明参数用户名,当客户端输入网址“http://host:port/project/home.seam?username=xyz”时,参数是通过seam组件中的username变量获取的:

@Logger private Log log;

@In(required = true)
private String username;

@In(required=false, scope=ScopeType.SESSION)
Usuario usuario;

@In @Out
Identity identity;

@In @Out
Credentials credentials;

public boolean authenticate(){

    log.info("authenticating {0}", username);

    try {

        UsuarioBean usuarioBean = (UsuarioBean) Component.getInstance(UsuarioBean.class, true);
        usuario = usuarioBean.validaUsuario(username);

        if (usuario == null){
            throw new AuthorizationException("login failed");
        }else{
            credentials.setUsername(usuario.getNome());
            return Boolean.TRUE;
        }

    }catch(Exception e){
        log.error("falha na autenticação do usuario {0} : {1}", username, e.getCause().toString());
        throw new AuthorizationException("login failed");
    }

}

我希望这些信息对您有用。祝你好运!

答案 1 :(得分:1)

这个Seam FAQ向您展示了如何访问HttpServletRequest对象。

HttpServletRequest对象有一个名为getRemoteUser()的方法。

此开源库http://spnego.sourceforge.net将允许您的应用服务器执行集成的Windows身份验证/ sso。

它作为servlet过滤器安装。

在你的web.xml文件中,定义过滤器,使其在任何Seam之前运行。

答案 2 :(得分:0)

我遇到了类似的问题,但在我的情况下没有页面:

Seam: login using external SSO application

我看到你采取了不同的路线。

我现在正在考虑的是创建一个JSF页面来获取我的参数,通过JS和autosubmit保存到表单值。这是一个但很难看,但应该有效。