0

The problem is that I don't completely understand what exceptions are handled and what aren't. I created new com.me.exceptions.InvalidPasswordException and populated it in the web.xml along with other exceptions:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>/view/login.xhtml</welcome-file>
    </welcome-file-list>
    <error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/view/login.xhtml?faces-redirect=true</location>
<error-page>
    <exception-type>com.me.exceptions.InvalidPasswordException</exception-type>
    <location>/view/loginWrongPass.xhtml?faces-redirect=true</location>
</error-page>
<error-page>
    <exception-type>java.io.IOException</exception-type>
    <location>/view/404.xhtml?faces-redirect=true</location>
</error-page>
<filter>
<filter-name>AuthFulter</filter-name>
<filter-class>com.me.beans.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFulter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
 </web-app>

I throw it from the my LoginBean:

@ManagedBean(name = "loginBean")
@SessionScoped
public class LoginBean implements Serializable {
    private static final long serialVersionUID = 1L;
    private String userName;
    private String password;

    !!!getters and setters are omitted

    public String login() throws InvalidPasswordException, IOException {
        int result = UserDao.login(userName, password);
        if (result == 0) {
            System.out.println("home");
            return "home";
        }
        else if (result == 1) {
            throw new InvalidPasswordException();
        }
    }
}

Why my InvalidPasswordException is not handled? Also if I throw IOException from the same place, it also doesn't work, though IOException is handled if it is thrown in the case of wrong URI in the request. Though I can see stack traces of both in the logs. Also I tried to throw exceptions from filters, it also works fine.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Battle_Slug
  • 2,055
  • 1
  • 34
  • 60
  • What container are you using? Why not mapping exceptions like [this](http://stackoverflow.com/a/7066536/1391249) way instead? – Tiny Jan 25 '15 at 05:16
  • BTW, the session scoped JSF managed bean appears to have been meant for login in which you are storing a user's password in a session which is ever not supposed to be. – Tiny Jan 25 '15 at 05:26
  • I am using Tomcat 7. I cannot use it this way because I have a task to use exceptions + I need to understand why it doesn't work this way. Also, I need specific behaviour for this case. – Battle_Slug Jan 25 '15 at 06:26
  • About your second comment - I have additional class that checks whether the credentials are correct, and if yes, stores them to the session. Exceptions thrown from that class also aren't handled... If it is not right thing to do, could you elaborate, how to do that? – Battle_Slug Jan 25 '15 at 06:28
  • I would implement a custom JSF validator (or a Hibernate Validator, if I think it makes more sense) to see, if the credentials provided by a user are valid/correct or not that leads to a separation of concerns - the validation logic can be placed in its own place thus, no need to put the validation logic into a managed bean. – Tiny Jan 25 '15 at 06:43
  • I would prefer a stateless approach (thus, a request scoped (JSF/CDI) managed bean) for login because sane users generally do not deliberately enter wrong credentials thus, no need to maintain any state even on a post back. If there is however, a need to maintain a state on post backs, a view scoped bean is sufficient hereby eliminating the need to have a session scoped bean for login. (A password stored into a session is likely to be hijacked by an attacker in several ways around, by the way). – Tiny Jan 25 '15 at 06:44
  • I am going to store only username in the session, not password. Do you have some example how to do what you say? About validators: I decided to opt out them as using them for check credentials is not what are they for. Their primarily concern is to validate formats, for example, but not to go to database and check credentials. Also, I need to provide a feedback to the user where the mistake in the entered data is, this is the task I cannot change. – Battle_Slug Jan 25 '15 at 06:58
  • "*I decided to opt out them as using them for check credentials is not what are they for. Their primarily concern is to validate formats, for example, but not to go to database and check credentials.*" No, this is utterly wrong (to the point, I am not going beyond my limit). This can surely be done by using a validator and in a more sane/intuitive way. (The thing might however, be different somewhat, if you happened to use some authentication/authorization mechanisms like JAAS (though it is possible to use a validator)). – Tiny Jan 25 '15 at 08:35
  • "*I need to provide a feedback to the user where the mistake in the entered data is, this is the task I cannot change.*" Again, it is a custom validator(s) of your choice (I posted some links in your previous question). – Tiny Jan 25 '15 at 08:36
  • Is this acceptable as dupe? http://stackoverflow.com/questions/10449862/what-is-the-correct-way-to-deal-with-jsf-2-0-exceptions-for-ajaxified-components/ – BalusC Jan 25 '15 at 22:58

1 Answers1

0

in general throw InvalidPasswordException or InvalidUsernameException is not good practice. User pass credentials if you find user from db you will do login, if not return null and redirect to another page or the same page show message "user not found" . You are not compare password for throw exception!. The first your method must be change to

 public String login(){
        UserObject resultObject = UserDao.login(userName, password);
        if (resultObject  == null) {
            System.out.println("user not found ");
            return "home";
        }

       if (resultObject != null) {
            System.out.println("user in database ");
            System.out.println("create user profile context "    +resultObject.getEmail() + " saving user object to session);    
return "userProfilePage";
        }

return null;
    }

After changing logic you can throw exception if you need instead of returning/redirecting , but throw / catch is not best practice " "Do NOT throw exceptions if you can avoid it, it makes your code MUCH slower ".

Armen Arzumanyan
  • 1,939
  • 3
  • 30
  • 56