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?
