Trace:
Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision | Next revision Both sides next revision | ||
jvx:code_snippets [2018/02/06 10:33] admin |
jvx:code_snippets [2018/02/06 10:34] admin |
||
---|---|---|---|
Line 2178: | Line 2178: | ||
ALTER TABLE CONTRACT enable ALL triggers; | ALTER TABLE CONTRACT enable ALL triggers; | ||
ALTER TABLE ACTIVITY enable ALL triggers; | ALTER TABLE ACTIVITY enable ALL triggers; | ||
+ | </file> | ||
+ | |||
+ | ==== Authentication/User logging ==== | ||
+ | |||
+ | Some applications need detailed information about successful or failed user logins. If you have such requirement, you could create a custom security manager to solve the problem. The security manager will be used for user authentication, so it's the right place to start. | ||
+ | |||
+ | We use the database security manager as base class: | ||
+ | |||
+ | <file java LoggingSecurityManager.java> | ||
+ | package com.sibvisions.apps.vaadin.web; | ||
+ | |||
+ | public class LoggingSecurityManager extends DBSecurityManager | ||
+ | { | ||
+ | private PreparedStatement psLockedUsers; | ||
+ | |||
+ | @Override | ||
+ | protected boolean isPasswordValid(ISession pSession, String pPassword) throws Exception | ||
+ | { | ||
+ | // additional check: locked user | ||
+ | |||
+ | ResultSet resultSet = null; | ||
+ | |||
+ | try | ||
+ | { | ||
+ | psLockedUsers.clearParameters(); | ||
+ | psLockedUsers.setString(1, pSession.getUserName()); | ||
+ | psLockedUsers.execute(); | ||
+ | |||
+ | resultSet = psLockedUsers.getResultSet(); | ||
+ | |||
+ | if (resultSet.next()) | ||
+ | { | ||
+ | throw new SilentAbortException(); | ||
+ | } | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | CommonUtil.close(resultSet); | ||
+ | } | ||
+ | |||
+ | return super.isPasswordValid(pSession, pPassword); | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public synchronized void validateAuthentication(ISession pSession) throws Exception | ||
+ | { | ||
+ | String result = null; | ||
+ | |||
+ | Throwable error = null; | ||
+ | |||
+ | try | ||
+ | { | ||
+ | super.validateAuthentication(pSession); | ||
+ | |||
+ | result = Constants.RESULT_OK; | ||
+ | } | ||
+ | catch (SilentAbortException sae) | ||
+ | { | ||
+ | result = Constants.RESULT_IGNORE; | ||
+ | error = sae; | ||
+ | |||
+ | throw sae; | ||
+ | } | ||
+ | catch (SecurityException se) | ||
+ | { | ||
+ | result = Constants.RESULT_DENIED; | ||
+ | error = se; | ||
+ | |||
+ | throw se; | ||
+ | } | ||
+ | catch (Exception ex) | ||
+ | { | ||
+ | result = Constants.RESULT_ERROR; | ||
+ | error = ex; | ||
+ | |||
+ | error(ex); | ||
+ | |||
+ | throw ex; | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | pSession.callAction("dbLog", Constants.TYPE_LOGIN, error, result); | ||
+ | } | ||
+ | catch (Throwable thr) | ||
+ | { | ||
+ | error(thr); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public synchronized void logout(ISession pSession) | ||
+ | { | ||
+ | String result = null; | ||
+ | Throwable error = null; | ||
+ | |||
+ | try | ||
+ | { | ||
+ | super.logout(pSession); | ||
+ | |||
+ | if (Boolean.parseBoolean((String)pSession.getProperty("userlogout"))) | ||
+ | { | ||
+ | result = Constants.RESULT_OK; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | result = Constants.RESULT_EXPIRED; | ||
+ | } | ||
+ | } | ||
+ | catch (Exception ex) | ||
+ | { | ||
+ | result = Constants.RESULT_ERROR; | ||
+ | error = ex; | ||
+ | |||
+ | error(ex); | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | pSession.callAction("dbLog", Constants.TYPE_LOGOUT, error, result); | ||
+ | } | ||
+ | catch (Throwable eLog) | ||
+ | { | ||
+ | error(eLog); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | protected void initStatements(Connection pConnection) throws Exception | ||
+ | { | ||
+ | super.initStatements(pConnection); | ||
+ | |||
+ | psLockedUsers = prepareStatement(pConnection, "select * from LOCKS where USERNAME = ?"); | ||
+ | } | ||
+ | |||
+ | } // LoggingSecurityManager | ||
+ | </file> | ||
+ | |||
+ | The clue is that the log method **dbLog** was implemented in the session LCO of our application because we re-use the business logic in our security manager. Here's the missing method: | ||
+ | |||
+ | <file java> | ||
+ | public void dbLog(int pAction, Throwable pError, String pStatus) | ||
+ | { | ||
+ | ILogger log = LoggerFactory.getInstance(getClass()); | ||
+ | |||
+ | log.info("Log action ", pAction, pError, pStatus); | ||
+ | | ||
+ | try | ||
+ | { | ||
+ | getDBAccess().executeProcedure("log", | ||
+ | pAction, | ||
+ | SessionContext.getCurrentSession().getUserName(), | ||
+ | new Timestamp(System.currentTimeMillis())); | ||
+ | } | ||
+ | catch (Exception ex) | ||
+ | { | ||
+ | log.error(ex); | ||
+ | } | ||
+ | } | ||
</file> | </file> |