spring security 可以获取当前登录的用户信息,同时提供了接口 来修改权限列表信息 ,
使用这个方法 ,可以动态的修改当前登录用户权限。
那么问题来了。。。
如果我是管理员 ,如何动态地修改用户的权限?比如vip权限?
按照以前的权限使用方法 ,修改数据库的权限信息后,当前用户需要重新登录,才能从数据库获取新的权限信息后再更新当前用户的权限列表,一般是管理员修改权限后,强制用户重新登录,
这样对用户很不友好 ,使用spring security 可以直接更新当前用户的权限 ,其实就是重新注册权限列表信息。
可是问题又来了。。。
spring security 不是只能修改当前登录用户的信息么?那么怎么修改别人的?
有两个解决方案:
(1)方案一:管理员在数据库修改用户权限数据后,检查该用户是否已经登录,未登录则操作结束,
如果已经登录,则使用websocket通知用户前端向后端Ajax发送一个修改当前权限的请求。
(2)方案二:管理员在数据库修改用户权限数据,检查该用户是否已经登录,未登录则操作结束,
如果已经登录,获取当前用户存在内存的session,根据session获取该用户的认证信息 ,取出权限列表后对其修改,然后重新注册权限列表。
2.操作准备一个配置好的spring boot+ spring security的工程 ,详细操作这里不演示 ,在我的其他随笔有详细记录
(1)目录结构
(2)添加方法
源码
package com.example.security5500.controller; import org.apache.commons.lang3.StringUtils; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.security.Principal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 作为授权类 ,用来动态更新权限 */ @RestController public class AuthorityController { //添加权限 ,参数是需要新增的权限名 @RequestMapping("/addAuth") public Map<String,Object> addAuth(String authName){ Map<String,Object> map = new HashMap<>(); if (StringUtils.isBlank(authName)){ map.put("data","权限名称不可空,参数名authName"); return map; } try { //======================================================== //这一段仅仅是更新当前登录用户的权限列表 ,登出后将释放 ,当再次从数据库获取权限数据时将还原 ,因此如果需要持久性的更改权限, // 还需要修改数据库信息 ,懒得写 ,这里就不做修改数据库演示了 // // 得到当前的认证信息 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // 生成当前的所有授权 List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities()); // 添加 ROLE_VIP 授权 updatedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + authName)); // 生成新的认证信息 Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities); // 重置认证信息 SecurityContextHolder.getContext().setAuthentication(newAuth); //======================================================== map.put("data","权限 "+authName+" 添加成功"); }catch (Exception e){ e.printStackTrace(); map.put("data","权限添加失败"); } return map; } //获取用户权限信息 @RequestMapping({"/info"}) @ResponseBody public Object info(@AuthenticationPrincipal Principal principal) { return principal; } /* {"authorities":[{"authority":"admin"},{"authority":"user"}], "details":{"remoteAddress":"0:0:0:0:0:0:0:1","sessionId":"1F57B8E39C5D1DB1F875D57D533DB982"}, "authenticated":true,"principal":{"password":null,"username":"xi","authorities":[{"authority":"admin"}, {"authority":"user"}],"accountNonExpired":true,"accountNonLocked":true, "credentialsNonExpired":true,"enabled":true},"credentials":null,"name":"xi"} */ //:5500/addAuth?authName=love1 //:5500/info }