Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use j_security_check jsf

I want to use j_security_check authentication in order to validate the user credentials.

Basically what I am trying to achieve is when the user press submit then in case he is using wrong credentials then a message (p:growl) will show and if it’s successful then the dialog will closed.

There are many examples in the web but unfortunately I still can’t understand how to complete this puzzle :(

In my project I am using primefaces 4.0 & weblogic 10.3.2.0 (JAVA EE 5).

some code example:

<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();

   }

Any guidelines and useful example will be much appreciated

Thanks

like image 210
angus Avatar asked Mar 21 '23 17:03

angus


2 Answers

You were submitting the form by PrimeFaces ajax. That's why it fails. The j_security_check handler doesn't understand incoming JSF/PrimeFaces-flavored ajax requests and can't handle them appropriately by returning the desired XML response. It has to be a regular (synchronous) submit.

Turn off the ajax thing:

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

By the way, your form declaration is clumsy. Just use <form> instead of <h:form>.

<form id="fLogin" action="j_security_check">
like image 82
BalusC Avatar answered Apr 05 '23 14:04

BalusC


after experimenting some strategy, i choose not to use j_security_check and implement auth this way:

@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
}

using this form inside /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>

and this 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>
like image 40
Michele Mariotti Avatar answered Apr 05 '23 15:04

Michele Mariotti