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?