The code I am looking at is a part of knox 1.1 which uses Shiro for 
authentication

Might have been solved in later versions

I am investigating this stack trace:

Caused by: org.apache.shiro.authz.AuthorizationException: There was a SQL error 
while authorizing user [admin]
         at 
org.apache.shiro.realm.jdbc.JdbcRealm.doGetAuthorizationInfo(JdbcRealm.java:345)
         at 
org.apache.shiro.realm.AuthorizingRealm.getAuthorizationInfo(AuthorizingRealm.java:341)
         at 
org.apache.shiro.realm.AuthorizingRealm.hasRole(AuthorizingRealm.java:573)
         at 
org.apache.shiro.authz.ModularRealmAuthorizer.hasRole(ModularRealmAuthorizer.java:374)
         at 
org.apache.shiro.mgt.AuthorizingSecurityManager.hasRole(AuthorizingSecurityManager.java:153)
         at 
org.apache.shiro.subject.support.DelegatingSubject.hasRole(DelegatingSubject.java:224)
         at 
org.apache.knox.gateway.filter.ShiroSubjectIdentityAdapter.doFilter(ShiroSubjectIdentityAdapter.java:69)
         at 
org.apache.knox.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:372)
         at 
org.apache.knox.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:272)
         at 
org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
         at 
org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
         at 
org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
         ... 52 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 
'roles_permissions'.
         at 
com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:254)
         at 
com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1608)
         at 
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:578)
         at 
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:508)
         at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7240)
         at 
com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2869)
         at 
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:243)
         at 
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:218)
         at 
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:434)
         at 
org.apache.shiro.realm.jdbc.JdbcRealm.getPermissions(JdbcRealm.java:401)
         at 
org.apache.shiro.realm.jdbc.JdbcRealm.doGetAuthorizationInfo(JdbcRealm.java:335)


This is logged in knox and an http 500 is returned to the caller, instead of a 
401

I have checked the following:

  *   SQLServerException is a valid subclass of SqlException
  *   doGetAuthorizationInfo catches this error and throws an 
AuthorizationException

            roleNames = getRoleNamesForUser(conn, username);
            if (permissionsLookupEnabled) {
                permissions = getPermissions(conn, username, roleNames);
            }

        } catch (SQLException e) {
            final String message = "There was a SQL error while authorizing 
user [" + username + "]";
            if (log.isErrorEnabled()) {
                log.error(message, e);
            }

            // Rethrow any SQL errors as an authorization exception
            throw new AuthorizationException(message, e);


  *   doFilter() of ShiroSubjectIdentityAdapter has no catches around the 
hasRole() call:

  public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain)
      throws IOException, ServletException {

    Subject subject = SecurityUtils.getSubject();

    // trigger call to shiro authorization realm
    // we use shiro authorization realm to look up groups
    subject.hasRole("authenticatedUser");

    CallableChain callableChain = new CallableChain(request, response, chain);
    SecurityUtils.getSubject().execute(callableChain);
  }

  *   hasRole() does not declare an exception and AuthorizationException is 
ultimately a subclass of RuntimeException
  *   AdviceFilter.cleanup() called from doFilter() seems to be wrapping this 
exception as a ServletException which might have caused this to be caught like 
a generic exception and a 500 returned instead:

        if (exception != null) {
            if (exception instanceof ServletException) {
                throw (ServletException) exception;
            } else if (exception instanceof IOException) {
                throw (IOException) exception;
            } else {
                if (log.isDebugEnabled()) {
                    String msg = "Filter execution resulted in an unexpected 
Exception " +
                            "(not IOException or ServletException as the Filter 
API recommends).  " +
                            "Wrapping in ServletException and propagating.";
                    log.debug(msg);
                }
                throw new ServletException(exception);
            }
        }

Did we lose a good, useful AuthorizationException? or is there more to this 
that I'm no reading properly?

Reply via email to