This likely depends how Shiro and the AdviceFitler was added into the
project, we would need a way to reproduce the problem.

I would also strongly suggest updating as well.

Either way, the easiest way to reproduce this might be to create a realm
that throws an AuthorizationException (you could extend one of the
text-based realms), this would take your DB out of the equation.

Keep us posted!


On Wed, Sep 11, 2019 at 12:26 PM jeff saremi <[email protected]> wrote:

> 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ç[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