I am building an auditing system and using security proxies to keep track of changes to entity beans. In addition to the actual data that has changed I am keeping track of the Principal(username) and the date that the modification has taken place. I want to store one additional piece of information, a simple Index that counts each login. So when I group a modifications I can tell exactly which authentication session it was done in. I have created an index in my database and a custom object that i'm trying to add to the credentials. Everytime I go to modify the Subject I am getting an IllegalStateException, Subject is Read-only. I have looked through both the login-config.xml file and the source for the DatabaseLoginModule and parent classes and can not find where this is being set. Am I configuring something incorrectly or is this code not the correct way to push a variable into the context?
DataSource is Postgres.
LoginIndex is a custom class with one variable and one accessor.
subject.getPublicCredentials().add(...) is the line that is failing. Thanks for any help.
The top check is because I only want to set the loginIndex one time.
protected void getSubject() {
if (this.subject!=null) return;
try {
InitialContext ic = new InitialContext();
Subject subject = (Subject)ic.lookup("java:comp/env/security/subject");
try {
DataSource ds = (DataSource) ic.lookup(MyBean.dbName);
Connection con = ds.getConnection();
String selectStatment = "select nextval('employeelogin_seq') as login";
PreparedStatement prepStmt = con.prepareStatement(selectStatment);
ResultSet rs = prepStmt.executeQuery();
if (rs.next())
subject.getPublicCredentials().add(new LoginIndex(rs.getInt("login")));
} catch (SQLException e1) {
e1.printStackTrace();
}
this.subject = subject;
} catch (NamingException e) {
e.printStackTrace();
throw new SecurityException("Subject Not Authenticated.");
}
}
You have no ability to modify the Subject returned from an authentication. If you want to do this you have to integrate via a custom login module.