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?