Thoughts on CSNS2 SecurityThe main goal of CSNS2 is to support multiple departments. From the security perspective, this requires that access control decisions be made based on department-level roles instead of systemwide roles. For example, a CS department administrator should be able to manage all CS department resources like classes and surveys, but none of the Tech department resources. The security implementation should be clean (which means separating security code from application code), simple (by taking full advantage of what Spring Security provides), and of course, efficient. Roles
Note that we no longer have ROLE_STUDENT as it would have the same privileges as ROLE_USER. And ROLE_USER and ROLE_GUEST are no longer necessary because we can use Spring EL like anonymous and authenticated to check. In theory we don't really need the department roles either as they kind of duplicate the information stored in Department, but having them as roles makes security checks easier to implement and much more efficient. Role ManagementThere's no user interface for managing systemwide roles:
Department roles are managed using the department management interface. In particular, each department keeps tracks of its own lists of administrators, faculty, instructors, and reviewers (see the Department class). When a user is added to (or removed from) a list, the system will automatically add (or remove) the corresponding role to the user. Only department administrators can access the department management interface. User ManagementThe isAccountNoneExpired() method in UserDetails can be used replace the ROLE_NEWUSER mechanism used in CSNS. In particular, for any auto-created account will be set as expired, and when a user tries to log in, an AccountExpiredException will be raised. In Spring Security configuration, this exception can be mapped to a registration page where the user can enter username, password etc. URL Access ControlApproach 1: same configuration as regular role-based url access control but use a custom role voter that recognizes department roles. Replace the default access decision manager with a custom one as shown in the example below:
RoleVoter and Approach 2: secure controller methods using @PreAuthorize. First of all, add the CGLIB2 dependency to the project:
Add <global-method-security> to <servlet-name>-servlet.xml as follows:
Note that to secure controllers, <global-method-security> has to be added to <servlet-name>-servlet.xml, not applicationContext.xml as these two files are not merged (and AOP has to be declared in each or something like that). The difference between pre-post-annotations and secured-annotations is that @PreAuthorize supports SpEL while @Secure can only check simple roles. Secure the controller method as shown in the following example:
This approach has some obvious advantages over the previous approach: no custom access decision manager required, much easier coding (SpEL vs. Voter, and department code extraction with @PathVariable). The only downside is that the performance may not be as good. Method Access ControlObject Access Control |