Unfortunately this is very hard for us to reproduce and even harder to upgrade 
and ask someone to try
This is a part of a more complex product and the problem was reported by some 
of our customers.
I am at this stage not too concerned with a fix. But rather the analysis of 
where the problem is.
Was my logic sound? Did I track it to the right spot? Where could Shiro be 
messing up a valid exception and re-throw it as a generic exception?

________________________________
From: Francois Papon <[email protected]>
Sent: Wednesday, September 11, 2019 5:24 AM
To: [email protected] <[email protected]>
Subject: Re: AuthorizationException Getting lost in Shiro


Hi,


I checked the Apache Knox project and the 1.1 version use the 1.2.6 version of 
Apache Shiro.


The latest 1.3.0 of Knox use the latest 1.4.1 of Shiro.


Can you make a test with the 1.3.0 of Knox?


regards,

François
[email protected]<mailto:[email protected]>

Le 11/09/2019 à 01:54, jeff saremi a écrit :
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