1 角色和资源映射关系确定
应用所需要的角色以及对应的资源在代码完成之后就已经完全确定,项目部署之后,不会有变动。这里可以使用spring的标准标签语言来实现
- 权限配置代码
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/list")
.access("hasRole('USER') or hasRole('ADMIN') or hasRole('DBA')")
.antMatchers("/newuser/**", "/delete-user-*").access("hasRole('ADMIN')").antMatchers("/edit-user-*")
.access("hasRole('ADMIN') or hasRole('DBA')").and().formLogin().loginPage("/login")
.loginProcessingUrl("/login").usernameParameter("ssoId").passwordParameter("password").and()
.rememberMe().rememberMeParameter("remember-me").tokenRepository(tokenRepository)
.tokenValiditySeconds(86400).and().csrf().and().exceptionHandling().accessDeniedPage("/Access_Denied");
}
- 展示层代码
<sec:authorize access="hasRole('ADMIN') or hasRole('DBA')">
<td><a href="<c:url value='/edit-user-${user.ssoId}' />" class="btn btn-success custom-width">edit</a></td>
</sec:authorize>
<sec:authorize access="hasRole('ADMIN')">
<td><a href="<c:url value='/delete-user-${user.ssoId}' />" class="btn btn-danger custom-width">delete</a></td>
</sec:authorize>
2 角色-资源映射关系动态变化
应用部署之后,角色和资源会动态修改。Spring标签就没办法实现了。
我的实现方式是,新写一个自己的展示层标签。在展示层代码中,将需要根据权限判断是否需要显示的代码片段写在自定义标签之中。
以freemarker为例,freemarker提供了一种自定义标签的实现方式,参考链接:http://freemarker.org/docs/pgui_datamodel_directive.html
- Java代码:
public class CheckPermission implements TemplateDirectiveModel {
AdminService adminService = (AdminService) SpringUtil.getBean("adminServiceImpl");
@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
// 禁止循环变量
if (loopVars.length != 0) {
throw new TemplateModelException("This directive doesn't allow loop variables.");
}
Object paramValue = params.get("resource");
String resource = ((SimpleScalar) paramValue).getAsString();
Admin admin = adminService.loadLoginAdmin();
if (null == admin) {
return;
}
Set<Role> roleSet = admin.getRoleSet();
boolean flag = false;
for (Role role : roleSet) {
if (!flag) {
Set<Resources> resourcesSet = role.getResourcesSet();
for (Resources resources : resourcesSet) {
if (resource.equals(resources.getValue())) {
body.render(env.getOut());
flag = true;
break;
}
}
} else {
break;
}
}
}
private HttpServletRequest getRequest() {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = attr.getRequest();
return request;
}
}
- ftl页面代码:
<#assign checkPermission = "CheckPermission"?new()>
<@checkPermission resource="http://www.baidu.com">
<input type="button"onclick="window.location.href='http://www.baidu.com';" value="1.百度一下">
</@checkPermission>