How to flush JAAS Cache from war application?
ybxiang.china Aug 14, 2013 10:29 PMDear all,
(1). After My EJB Client connects to my EJB(packed in an ear) deployed JBoss AS 7, I change its roles(add or remove), the change take effect immediately after I excecute bellow method on server side.
(2). But, After one user loggs in my web application(packed in an ear), I change its roles(add or remove), the change does NOT take effect immediately after I excecute bellow same method on server side. Why? How to resolve this problem?
Now, Let me discribe my problem in details.
1. My Entities
(a) DB Relation:
(b) Codes:
@Entity
public class User implements Serializable{
private Long id;
private String username;//登录名
private String hashedPassword;
private Boolean activated = false;
private Boolean locked = false;
//..
private Set<UserGroup> userGroups;
//...
@ManyToMany(targetEntity=UserGroup.class,fetch = FetchType.LAZY)
@JoinTable(name = "User_UserGroup",
joinColumns = @JoinColumn(name="user_id"),
inverseJoinColumns = @JoinColumn(name="usergroup_id")
)
public Set<UserGroup> getUserGroups() {
return userGroups;
}
//...
}
@Entity
public class UserGroup implements Serializable {
private Integer id;
private String name;
private Set<JaasRole> jaasRoles;
...
@ManyToMany(targetEntity=JaasRole.class,fetch = FetchType.LAZY)
@JoinTable(name = "UserGroup_JaasRole",
joinColumns = @JoinColumn(name="usergroup_id"),
inverseJoinColumns = @JoinColumn(name="jaasrole_id")
)
public Set<JaasRole> getJaasRoles() {
return jaasRoles;
}
//...
}
@Entity
public class JaasRole implements Serializable {
private Integer id;
private String name;
private String displayName = "";
}
2. DB Records:
2.1 JaasRole
2.2 UserGroup
2.3 UserGroup_JaasRole
2.4 User
2.5 User_UserGroup
3. Security domain configuration in standalone.xml
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="dsJndiName" value="java:jboss/datasources/ybxiangForumMySqlDataSource"/>
<module-option name="principalsQuery" value="SELECT hashedPassword FROM User WHERE username=? and activated=true and locked=false"/>
<module-option name="rolesQuery" value="SELECT DISTINCT r.name, 'Roles' FROM User u, User_UserGroup ug, UserGroup_JaasRole gr, JaasRole r WHERE u.id=ug.user_id AND ug.usergroup_id=gr.usergroup_id AND gr.jaasrole_id=r.id AND u.username=?"/>
<module-option name="hashAlgorithm" value="SHA-256"/>
<module-option name="hashEncoding" value="Base64"/>
<module-option name="hashCharset" value="UTF-8"/>
<module-option name="unauthenticatedIdentity" value="guest"/>
</login-module>
4. My page list.xhtml
test link: http://127.0.0.1/faces/list.xhtml?mid=318
...
| <h:panelGroup layout="block" rendered="#{request.isUserInRole('318')}"> | ||||
| <h:form id="form"> | ||||
| bla bla... | ||||
| </h:form> | ||||
| </h:panelGroup> |
...
Now, the user(id=10010,name = 'tester') belong to UserGroup(id=2002) which is authorized with JAAS Role(id=10318, name='318').
5. Test case 1
5.1 The user "tester" log in and visit page: http://127.0.0.1/faces/list.xhtml?mid=318
He can see the "bla bla...".
This is what I expect.
5.2 Now, I (the admin) run bellow java codes to delete tester's usergroup and flush jaas cache:
| @RolesAllowed({KnownJaasRoles.ADMINISTRATOR}) | ||
| public void deleteUserGroup(Long userId, Integer userGroupId){ | ||
| em.createNativeQuery(User.NativeQuery_jpql_DeleteUserGroup) | ||
| .setParameter(User.NativeQuery_param_DeleteUserGroup_userId, userId) | ||
| .setParameter(User.NativeQuery_param_DeleteUserGroup_userGroupId, userGroupId) | ||
| .executeUpdate(); | ||
| // | ||
| User u = em.find(User.class, userId); | ||
| jaasCacheSession.flushJavaarmForumSecurityDomainJaasCache(u.getUsername()); | ||
| } |
@RolesAllowed({KnownJaasRoles.ADMINISTRATOR})
public void flushJaasCache(String securityDomain, String jaasUsername) {
try {
Object[] params = { jaasUsername };
String[] signature = { "java.lang.String" };
MBeanServerConnection mbeanServerConnection = java.lang.management.ManagementFactory.getPlatformMBeanServer();
ObjectName mbeanName = new ObjectName("jboss.as:subsystem=security,security-domain="+ securityDomain);
mbeanServerConnection.invoke(mbeanName, "flushCache", params,signature);
} catch (Exception e) {
throw new SecurityException(e);
}
}
@RolesAllowed({KnownJaasRoles.ADMINISTRATOR})
public void flushJavaarmForumSecurityDomainJaasCache(String jaasUsername){
flushJaasCache(coreService.getJavaarmForumJaasSecurityDomain(),jaasUsername);
}
5.3 Result:
(a) The record(10010, 20002) has been removed from "user_usergroup"
(b) But, the tester can still see "bla bla..." in list.xhtml( http://127.0.0.1/faces/list.xhtml?mid=318 )
This is NOT What I expect!
Now, the tester log off, log in again and visit list.xhtml( http://127.0.0.1/faces/list.xhtml?mid=318 ),
This time, he can NOT see the "bla bla..."
This is What I expect.
6. Test case 2 (no problem)
Let's restore steps 1~4,
6.1 The user "tester" log in and visit page: http://127.0.0.1/faces/list.xhtml?mid=318
He can see the "bla bla...".
This is what I expect.
6.2 Now, I (the admin) run bellow java codes to delete tester's usergroup( do NOT flush jaas cache):
| @RolesAllowed({KnownJaasRoles.ADMINISTRATOR}) | ||
| public void deleteUserGroup(Long userId, Integer userGroupId){ | ||
| em.createNativeQuery(User.NativeQuery_jpql_DeleteUserGroup) | ||
| .setParameter(User.NativeQuery_param_DeleteUserGroup_userId, userId) | ||
| .setParameter(User.NativeQuery_param_DeleteUserGroup_userGroupId, userGroupId) | ||
| .executeUpdate(); | ||
| // | ||
| User u = em.find(User.class, userId); | ||
| // jaasCacheSession.flushJavaarmForumSecurityDomainJaasCache(u.getUsername()); | ||
| } |
6.3 Result
Now, the tester do NOT log off, just close all browsers.
Then, he login and visit list.xhtml( http://127.0.0.1/faces/list.xhtml?mid=318 ),
This time, he can still see the "bla bla..."
This is what I expect, because the cache is NOT flushed.
7. My Question/Problem
ONLY 5.3 is NOT what I expect.
It seems that 'tester''s jaas roles is NOT flushed immediately/successfully in step 5.2, because it does NOT take effect immediately in step 5.3 (b).
Is my description clear?





