@Component
public class ResourceConfigAttributeHolder {
//缓存 url对应权限 只有这些权限才能访问url 菜单url,只有这些权限才能访问该菜单url
private Map<String, Collection<ConfigAttribute>> cache = null;
private static final String LOAD_RESOURCE_AUTHORITY = "select r.link, a.name from SEC_RESOURCE r, SEC_ROLE_RESOURCE ra, SEC_ROLE a where r.id=ra.resource_id and a.id=ra.role_id";
private static final String LOAD_MENU_AUTHORITY = "select m.link, a.name from SEC_MENU m, SEC_ROLE_MENU ma, SEC_ROLE a where m.id=ma.menu_id and a.id=ma.role_id";
@Autowired
private JdbcTemplate template;
public Collection<ConfigAttribute> getAllConfigAttributes() {
if(cache == null){
fullCache();
}
Collection<ConfigAttribute> entrys = new HashSet<ConfigAttribute>();
for(Collection<ConfigAttribute> entry:cache.values()){
entrys.addAll(entry);
}
return entrys;
}
private synchronized void fullCache() {
cache = new HashMap<String, Collection<ConfigAttribute>>();
template.query(LOAD_RESOURCE_AUTHORITY, new String[] {}, new ResultSetExtractor<Map<String, Collection<ConfigAttribute>>>() {
public Map<String, Collection<ConfigAttribute>> extractData(ResultSet rs)
throws SQLException, DataAccessException {
String resource;
String authority;
while(rs.next()){
resource = rs.getString(1);
authority = rs.getString(2);
if(!cache.containsKey(resource)){
Collection<ConfigAttribute> attributes = new LinkedList<ConfigAttribute>();
attributes.add(new SecurityConfig(authority));
cache.put(resource, attributes);
}
}
return cache;
}
});
template.query(LOAD_MENU_AUTHORITY, new String[] {}, new ResultSetExtractor<Map<String, Collection<ConfigAttribute>>>() {
public Map<String, Collection<ConfigAttribute>> extractData(ResultSet rs)
throws SQLException, DataAccessException {
String menu;
String authority;
while(rs.next()){
menu = rs.getString(1);
authority = rs.getString(2);
if(StringUtils.isBlank(menu)){
continue;
}
if(!cache.containsKey(menu)){
Collection<ConfigAttribute> attributes = new LinkedList<ConfigAttribute>();
attributes.add(new SecurityConfig(authority));
cache.put(menu, attributes);
}
}
return cache;
}
});
}
public Map<String, Collection<ConfigAttribute>> getResourceConfigAttributeMap() throws IllegalArgumentException {
if(cache == null){
fullCache();
}
return cache;
}
}
当完成用户认证请求时,认证结果会存储到Authentication对象中,getAuthenticaties()方法将返回用户的身份,在大部分场合,用户身份就是用户持有的角色,比如
"ROLE_USER"/"ROLE_ADMIN",GrantedAuthority接口的定义如下,他不仅仅暴漏了当个方法,它将返回用户身份的字符串表示
GrantedAuthority
public List<Menu> getAccessableMenus(Set<GrantedAuthority> authorities) {
if (authorities.size() == 0) {
return Collections.EMPTY_LIST;
}
Map<String, Set<GrantedAuthority>> params = new HashMap<String, Set<GrantedAuthority>>();
params.put("authorities", authorities);
String hql = queryBuilder.getQueryString("hqlQueryAccessableMenus", params);
List<String> l = new LinkedList<String>();
for (GrantedAuthority auth : authorities) {
l.add(auth.getAuthority());
}
return queryListByHql(hql, l.toArray(new String[] {}));
}
针对用户密码的加密工作,DaoAuthenticationProvider同时暴漏了passwordEncoder和saltSource属性
揭露JdbcDaoImpl
在采用RDBMS存储用户信息时,开发者必须提供相应的RDBMS表,否则用户信息的存储将是大问题
默认:JdbcDaoImpl会采用如下sql获得用户名、密码、启用状态
select username,password,enabled from user where username=?
类似的,jdbcDaoImpl会采用如下sql获得用户授权信息(角色集合)
select username,authority from authorities where username=? 源码中可读
FilterSecurityInterceptor对用户进行授权,他也可能需要完成用户的认证