如何使用j_security_check jsf

时间:2014-02-01 16:04:34

标签: jsf-2 primefaces j-security-check

我想使用j_security_check身份验证来验证用户凭据。

基本上我想要实现的是当用户按下提交时,如果他使用了错误的凭据,那么将显示一条消息(p:growl),如果它成功,则对话框将关闭。

网上有很多例子,但不幸的是我仍然无法理解如何完成这个难题:(

在我的项目中,我正在使用primefaces 4.0& weblogic 10.3.2.0(JAVA EE 5)。

一些代码示例:

<p:dialog id="dialog" widgetVar="dlg" resizable="false"> 
    <h:form id="fLogin" prependId="false"
            onsubmit="document.getElementById('fLogin').action = 'j_security_check';">        
        <h:panelGrid columns="2" cellpadding="5">  
            <h:outputLabel for="j_username" value="Username:" />  
            <p:inputText value="#{expBean.username}"   
                         id="j_username" label="username"/>  
            <h:outputLabel for="j_password" value="Password:" />  
            <h:inputSecret value="#{expBean.password}"   
                           id="j_password" label="password"/>  
            <p:commandButton id="submitButton" 
                             value="Submit"
                             actionListener="#{expBean.run}" /> 
        </h:panelGrid> 
    </h:form>
</p:dialog>

的web.xml

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<security-constraint>
    <web-resource-collection>
        <web-resource-name>main</web-resource-name>
        <description/>
        <url-pattern>main.jsf</url-pattern>
        <http-method>POST</http-method>
    </web-resource-collection>
</security-constraint>
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>my-realm</realm-name>
</login-config>
<security-role>
    <description/>
    <role-name>MyRole</role-name>
</security-role>

exeBean:

   public void run() {


      FacesContext facesContext = FacesContext.getCurrentInstance();

   }

非常感谢任何指南和有用的示例

由于

2 个答案:

答案 0 :(得分:4)

您正在提交PrimeFaces ajax的表格。这就是它失败的原因。 j_security_check处理程序不了解传入的JSF / PrimeFaces风格的ajax请求,并且无法通过返回所需的XML响应来适当地处理它们。它必须是常规(同步)提交。

关掉ajax的事情:

<p:commandButton ... ajax="false" />

顺便说一句,你的表格声明很笨拙。只需使用<form>代替<h:form>

<form id="fLogin" action="j_security_check">

答案 1 :(得分:1)

在尝试了一些策略之后,我选择不使用j_security_check并以这种方式实现auth:

@ManagedBean
@ViewScoped
public class AuthBean implements Serializable
{
    private static final long serialVersionUID = 1L;
    private static final Logger logger = LoggerFactory.getLogger(AuthBean.class);

    @EJB
    private PersistenceService service;

    @ManagedProperty("#{user}")
    private UserBean userBean;

    private String email;
    private String password;
    private String originalURL;

    @PostConstruct
    public void init()
    {
        logger.debug("called");

        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        originalURL = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);

        if(originalURL == null)
        {
            originalURL = externalContext.getRequestContextPath();
        }
        else
        {
            String originalQuery = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING);

            if(originalQuery != null)
            {
                originalURL += "?" + originalQuery;
            }
        }

        logger.debug("originalURL: {}", originalURL);
    }

    public void login() throws IOException
    {
        logger.debug("called");
        logger.debug("originalURL: {}", originalURL);

        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext externalContext = context.getExternalContext();
        HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();

        try
        {
            request.login(email, password);
        }
        catch(ServletException e)
        {
            JsfUtils.addErrorMessage(e, "authentication failed");
            return;
        }

        Person person = service.queryOne(Person.class, "SELECT x FROM Person x WHERE x.email = ?1", email);
        if(person == null)
        {
            JsfUtils.addErrorMessage("authorization failed");
            return;
        }

        userBean.setPerson(person);
        externalContext.redirect(originalURL);
    }

    public void logout() throws IOException
    {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        externalContext.invalidateSession();
        externalContext.redirect(externalContext.getRequestContextPath());
    }

    // getters/setters
}

在/login.xhtml中使用此表单:

<h:form>
    <p:panel header="#{bundle.login}">
        <h:panelGrid columns="3">
            <h:outputLabel for="email" value="#{bundle.email}" />
            <h:outputLabel for="password" value="#{bundle.password}" />
            <h:panelGroup />

            <p:inputText id="email" value="#{authBean.email}" label="#{bundle.email}" size="32" />
            <p:password id="password" value="#{authBean.password}" label="#{bundle.password}" feedback="false" size="32" />
            <p:commandButton value="#{bundle.login}" action="#{authBean.login}" icon="ui-icon ui-icon-check" />
        </h:panelGrid>
    </p:panel>
</h:form>

和这个login-config:

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>some-realm-name</realm-name>
    <form-login-config>
        <form-login-page>/login.jsf</form-login-page>
        <form-error-page>/login.jsf</form-error-page>
    </form-login-config>
</login-config>