How can I do Spring Security Authentication from JSF Form

I created a simple JSF login page and I am trying to integrate it with spring security.

Here is the form element from login.xhtml

<h:form> <h:outputLabel value="User Id:" for="userId"/> <h:inputText id="j_username" label="User Id" required="true" value="#{loginBean.name}" > </h:inputText> <h:outputLabel value="Password: " for ="password"/> <h:inputSecret id="j_password" value="#{loginBean.password}" /> <h:commandButton value="Submit" action="#{j_spring_security_check}" /> </h:form> 

But the displayed html page has something like below. Take a look at the action of the form and input tag names

Form element

  <form id="j_idt6" name="j_idt6" method="post" action="/jsfproject2/faces/login.xhtml" enctype="application/x-www-form-urlencoded"> 

And input tags

  User Id:</label><input id="j_idt6:j_username" type="text" name="j_idt6:j_username" /> 

Now I want the form action to be /j_spring_security_check , and the input fields are "j_username" and j_password

How can we achieve this?

+6
source share
2 answers

There are two possibilities for spring security to work.

Use prependId="false" in JSF form

Since <h:form> is a naming container, it adds the identifier of its children with the specified id or auto-generated identifier, since Spring Security expects identifiers to remain unclean, just do not add identifiers:

  <h:form prependId="false"> <h:outputLabel value="User Id: " for="userId" /> <h:inputText id="j_username" label="User Id" required="true" value="#{loginBean.name}" /> <h:outputLabel value="Password: " for ="password" /> <h:inputSecret id="j_password" value="#{loginBean.password}" /> <h:commandButton value="Submit" action="#{loginBean.login}" /> </h:form> 

Please note that #{j_spring_security_check} is the wrong action method: it must be #{loginBean.login} with the following contents:

 public String login() { //do any job with the associated values that you've got from the user, like persisting attempted login, etc. FacesContext facesContext = FacesContext.getCurrentInstance(); ExternalContext extenalContext = facesContext.getExternalContext(); RequestDispatcher dispatcher = ((ServletRequest)extenalContext.getRequest()).getRequestDispatcher("/j_spring_security_check"); dispatcher.forward((ServletRequest)extenalContext.getRequest(), (ServletResponse)extenalContext.getResponse()); facesContext.responseComplete(); return null; } 

Basically, all you have to do is send to /j_spring_security_check and specify j_username and j_password as request parameters.

Use a regular HTML form

Basically, there is no particular need to contact the JSF form on this issue if you do not need to do any additional things besides authentication, and a simple HTML form is enough for Spring security to do its job.

 <form action="/j_spring_security_check" method="POST"> <label for="j_username">User Id: </label> <input id="j_username" name="j_username" type="text" /> <label for="j_password">Password: </label> <input id="j_password" name="j_password" type="password"/> <input type="submit" value="Submit"/> </form> 
+14
source

Here is how I did it:

 <form action="${request.contextPath}/appLogin" method="POST"> <h:form prependId="false"> <p:inputText id="app_username" placeholder="Username" name="app_username" styleClass="Wid80 TexAlCenter Fs18" required="true"/> <p:password id="app_password" placeholder="Password" name="app_password" label="Password" required="true" styleClass="Wid80 TexAlCenter Fs18"/> <button type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only Wid60"> <span class="ui-button-text">Login</span> </button> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> </h:form> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> </form> 

I use Premium Theme Ronin from Primefaces and custom login URLs such as "appLogin" and custom settings such as "app_username".

+1
source

Source: https://habr.com/ru/post/945756/


All Articles