给定一个场景,控制器中有HTML内容或某些方法,只允许通过“a”角色进行访问.
从上面,我们通过使用@hasRole(“a”)实现
但是,就我而言,角色是动态的:
例如,admin添加一个新角色“b”,并且能够访问这些内容.
那怎么办呢?
>我尝试过ACL,但这只是用id来保护域对象.
>有一个名为hasAuthority的注释,但我无法搜索
来自互联网的任何事情.
>有一个ObjectIdentityImpl,不是真的
如何实施.
>经过研究,ACL更多地放在对象的安全列表中.
示例:您想要保护员工表,一些员工记录(如CEO,经理)只能由高级管理人员访问.所有员工都可以查看其他员工的记录.这就是ACL要做的事情.
但是,当我们需要保护一些方法,控制器,URL,静态内容…… ACL不适用于此.我们需要使用hasAuthority或hasPermission或hasRole或……
>在某些Web系统中,只有很少的角色,管理员和用户.对于这种情况,hasAuthority或hasRole就足够了.你只是为你想要保护的资源注释@hasRole(‘admin’).
但是,在某些系统中,存在动态角色,例如:admin创建新角色“temporary_user”,但控制器或方法由@hasRole(‘user’)注释,“temporary_user”无法访问.
在这种情况下,根据我的理解,几乎没有办法.
>根据您想要保护的资源数量创建许多角色.例如:将’role_getRecord’赋值给getRecords(),将’role_writeRecord’赋值给writeRecord().这是一种不改变spring安全机制的方法,但是在你的数据库表上会有很多角色,而且系统会比较复杂,会有更多.
> @hasPermission – 这就是我现在使用的.我创建一个CustomGrantedAuthority,以便更灵活地实现.我有一个CustomUserDetailsService和CustomSpringSecurityUser,当用户登录时将使用CustomGrantedAuthority集合创建CustomSpringSecurityUser,然后将CustomSpringSecurityUser返回给CustomUserDetailsService.我也有一个CustomPermission来验证权限.
如果您认为有用,请投票UP,如果我错了或者有更好的方法,请发表评论.
这是我的代码
CustomSpringSecurityUser
public class CustomSpringSecurityUser implements UserDetails,CredentialsContainer {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private String password;
private final String username;
private final Set
CustomGrantedAuthority
public class CustomGrantedAuthority implements GrantedAuthority{
private String role;
private String permission,action;
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
@Override
public String getAuthority() {
return role;
}
}
CustomeUserDetailsService
@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private OcUserService userService;
private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
sg.com.xx.xx.table.OcUser u = userService.findByLoginname(username);
String pass = sg.com.xx.xx.table.OcUser.byteToHex(u.getPassword());
Collection extends GrantedAuthority> permissionList = userService.getPermissionByUserId(u.getId());
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
CustomSpringSecurityUser user = new CustomSpringSecurityUser(u.getLoginname(),pass,enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,permissionList);
return user;
} catch (Exception e) {
logger.error("==============================================");
logger.error(e.toString());
return null;
}
}
}
CustomPermission
public class CustomPermission implements PermissionEvaluator {
@Override
public boolean hasPermission(Authentication authentication,Object targetDomainObject,Object permission) {
Collection extends GrantedAuthority> x = authentication.getAuthorities();
for(Object o : x)
{
CustomGrantedAuthority y = (CustomGrantedAuthority) o ;
if(y.getPermission().equals(targetDomainObject) )
if( y.getAction().equals(permission) )
return true;
}
return false;
}
@Override
public boolean hasPermission(Authentication authentication,Serializable targetId,String targetType,Object permission) {
int a = 5;
return true;
}
}