Dear Shiro Team:
    In my opnion, 
org.apache.shiro.authc.AbstractAuthenticator.authenticate(AuthenticationToken 
token)  handles exception inappropriately.Below is the code indicates the 
problem  with my note in red:


        // 
org.apache.shiro.authc.AbstractAuthenticator.authenticate(AuthenticationToken 
token)
        public final AuthenticationInfo authenticate(AuthenticationToken token) 
throws AuthenticationException {


        if (token == null) {
            throw new IllegalArgumentException("Method argumet (authentication 
token) cannot be null.");
        }


        log.trace("Authentication attempt received for token [{}]", token);


        AuthenticationInfo info;
        try {
            info = doAuthenticate(token);
            if (info == null) {
                String msg = "No account information found for authentication 
token [" + token + "] by this " +
                        "Authenticator instance.  Please check that it is 
configured correctly.";
                throw new AuthenticationException(msg);
            }
        } catch (Throwable t) {
            AuthenticationException ae = null;
            if (t instanceof AuthenticationException) {
                ae = (AuthenticationException) t;
            }
            // Indeed, the Throwable t which is not caused by auhtentication 
problem but other such as a database problem is wrapped to be  a 
AuthenticationException instance, but details including exception message and 
stacktrace are missing and the follow-up handling makes the raw //Throwable t 
ignored.
            if (ae == null) {
                //Exception thrown was not an expected AuthenticationException. 
 Therefore it is probably a little more
                //severe or unexpected.  So, wrap in an 
AuthenticationException, log to warn, and propagate:
                String msg = "Authentication failed for token submission [" + 
token + "].  Possible unexpected " +
                        "error? (Typical or expected login exceptions should 
extend from AuthenticationException).";
                ae = new AuthenticationException(msg, t);
            }
            try {
                notifyFailure(token, ae);
            } catch (Throwable t2) {
                if (log.isWarnEnabled()) {
                    String msg = "Unable to send notification for failed 
authentication attempt - listener error?.  " +
                            "Please check your AuthenticationListener 
implementation(s).  Logging sending exception " +
                            "and propagating original AuthenticationException 
instead...";
                    log.warn(msg, t2);
                }
            }




            throw ae;
        }


        log.debug("Authentication successful for token [{}].  Returned account 
[{}]", token, info);


        notifySuccess(token, info);


        return info;
    }



    And then, the Authencication instance that wraps the orignal Thowable 
instance is thrown all the way, and get dumped below:
    
    // org.apache.shiro.web.filter.authc.AuthenticatingFilter
    protected boolean executeLogin(ServletRequest request, ServletResponse 
response) throws Exception {
        AuthenticationToken token = createToken(request, response);
        if (token == null) {
            String msg = "createToken method implementation returned null. A 
valid non-null AuthenticationToken " +
                    "must be created in order to execute a login attempt.";
            throw new IllegalStateException(msg);
        }
        try {
            Subject subject = getSubject(request, response);
            subject.login(token);
            return onLoginSuccess(token, subject, request, response);
        } catch (AuthenticationException e) {
            // ignore the AuthenticationException instance, only return a 
boolean, make the original Throwable ignored and it is hard to find out the 
mistake in the authentication progress. 
            return onLoginFailure(token, e, request, response);
        }
    }



    Above shows the problem, that makes the origianl Throwable instance 
disappeared. In my situation, a Hibernate Exception was thrown, but no message 
showed, which made me take a long time to find out the mistake .
    English is not my native laguage. I know I express not well in English, 
hope it does not influence you to understand my opnion.


Yours respectfully,
Liang Weiwei

Reply via email to