Apache Shiro,无法将值从登录表单传递到支持 bean

Posted

技术标签:

【中文标题】Apache Shiro,无法将值从登录表单传递到支持 bean【英文标题】:Apache Shiro, can not pass values from login form to backing bean 【发布时间】:2015-05-09 07:01:54 【问题描述】:

我无法将登录表单中的值传递给支持 bean,以通过我的 Web 应用程序中的 apache shiro 对用户进行身份验证。有人知道为什么吗?

shiro.ini

 [main]
authc.loginUrl = /login.jsf
authc.successUrl = /pages/welcome.jsf

[users]
admin = 1234

[urls]
/login.jsf = authc
/pages/** = authc

login.xhtml

<ui:define name="content">
<div id="login_form">
    <h:form prependId="false">
        <center>
        <h1>Sign in <p:link value="or create an account" outcome="registration" style="color: #0A9CE5; text-decoration: none;" /></h1>
            <table> 
                <tr>
                    <td><p:inputText id="username" value="#shiroLoginBean.username" placeholder="Login" required="true" /></td>
                </tr>
                <tr>
                    <td><p:password id="password" value="#shiroLoginBean.password" placeholder="Password" required="true" /></td>
                </tr>
            </table>
        </center>
        <p:commandButton value="Sign in" action="#shiroLoginBean.doLogin" />
    </h:form>
</div>

豆:

    package utils.security;

import java.io.IOException;
import java.io.Serializable;

import javax.ejb.Stateless;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Named("shiroLoginBean")
@Stateless
@ViewScoped
public class ShiroLoginBean implements Serializable 
    private static final long serialVersionUID = 1L;

    private static final Logger log = LoggerFactory.getLogger(ShiroLoginBean.class);

    private String username;
    private String password;

    public ShiroLoginBean() 

    

    /**
     * Try and authenticate user. 
     */
    public void doLogin() 
        Subject subject = SecurityUtils.getSubject();   
        UsernamePasswordToken token = new UsernamePasswordToken(getUsername(), getPassword());

        try 
            subject.login(token);
            FacesContext.getCurrentInstance().getExternalContext().redirect("pages/welcome.jsf");
         catch (UnknownAccountException ex) 
            log.error(ex.getMessage(), ex);
         catch (IncorrectCredentialsException ex) 
            log.error(ex.getMessage(), ex);
         catch (LockedAccountException ex) 
            log.error(ex.getMessage(), ex);
         catch (AuthenticationException | IOException ex) 
            log.error(ex.getMessage(), ex);
         finally 
            token.clear();
        
    

    //~ Setters and Getters
    public String getPassword() 
        return password;
    
    public void setPassword(String password) 
        this.password = password;
    

    public String getUsername() 
        return username;
    
    public void setUsername(String username) 
        this.username = username;
    


问题出在这一行... UsernamePasswordToken token = new UsernamePasswordToken(getUsername(), getPassword()); ... getUsername 和 getPassword 始终为空。非常感谢您的回答!!

【问题讨论】:

【参考方案1】:

您的 @ViewScoped 导入错误 - 因为您使用 @Named(意味着它是一个 CDI bean),所以您应该使用

import javax.faces.view.ViewScoped; 

由于您省略了相关范围,您将获得 @Dependent 范围,我从未见过它的用途,但它的寿命很短(输入将绑定到一个 bean,但当 doLogin() 运行时它将是在一个新的)。

【讨论】:

感谢您的反应。所以我必须删除无状态注释? JBoss 有问题.. 但在这里我认为 Stateless 没有意义。 我同意,是的,不需要使它成为 EJB。结果如何? 没什么。我只想在登录后重定向:FacesContext.getCurrentInstance().getExternalContext().redirect("pages/welcome.jsf"); 据我所知,你根本不需要 bean(我对 Shiro 没有经验):balusc.blogspot.dk/2013/01/… 是的,我需要角色分离、日志记录等。在删除无状态注释后,更改您建议的导入并将 action="#shiroLoginBean.doLogin" 更改为 actionListener="#shiroLoginBean .doLogin()" 我已经解决了。Jacqen 是我在 GoT 和堆栈中最喜欢的字符 :) 谢谢!

以上是关于Apache Shiro,无法将值从登录表单传递到支持 bean的主要内容,如果未能解决你的问题,请参考以下文章

如何将值从表单传递到数据表

如何将值从mysql传递到create视图中的表单域

将值从表单传递到表单

JSP 将值从表传递到表单

如何将值从mysql传递到创建视图中的表单字段

如何将值从一个表单传递到另一个表单的动态创建的控件