我们在使用spring security的时候可以通过好几种方法获取用户信息,但是今天这篇文章介绍的是一个笔者觉得最优雅的实现;借鉴现有春天的安全控制器自动注入参数的方法,我们来进一步的实现更适合我们业务的用户信息获取方法;
现在spring security会在控制器自动注入认证/Userdetails等参数,我们拿到这些对象之后还需要一些处理才可以拿到我们需要的信息,例如用户身份证;那获取用户身份证这个步骤其实可以切片的,我们直接在控制器的参数绑定之前,获取到我们需要的用户信息,然后添加到请求的参数里的面,就可以实现获取用户信息,控制器里面使用参数名可以直接接收参数;
首先我们这个功能的实现遇到额第一个障碍就是默认的HttpServletRequest是没有提供修改参数的方法的,那么我们即使获取到用户信息也无法写入请求;解决这个问题就需要自己实现一个HttpServletRequestWrapper,再使用一个过滤器替换原来的请求;
进口javax.servlet.http.HttpServletRequest; 进口javax.servlet.http.HttpServletRequestWrapper; 进口活动; 进口java.util.HashMap; 进口java.util.Map; 进口java.util.Vector;/* * * @author sunhao *在2019-12-09 14:39:52 @date创建 */公开课UserInfoRequest延伸HttpServletRequestWrapper { 私人MapgetParameterNames () { 返回新Vector<祝辞(params.keySet ()) . elements (); }/* * *重写getParameter方法 * * @param名字参数名 * @return返回参数的值 */@Override 公共字符串getParameter(字符串名称){ String[]值=params.get(名称); 如果(值==null | |值。长度==0){ 返回null; } 返回值[0]; } @Override 公共String [] getParameterValues(字符串名称){ String[]值=params.get(名称); 如果(值==null | |值。长度==0){ 返回null; } 返回值; }/* * *增加参数 * * @param名字参数名 * @param值参数的值 */公共空间addParameter(字符串名称、对象价值){ 如果(价值!=null) { 如果值运算符字符串[]){ 参数个数。把(名称、(String[])价值); }else if(值运算符字符串){ 参数个数。把(名称、新String[]{(字符串)值}); 其他}{ 参数个数。把(名称、新String [] {String.valueOf(值)}); } } } }
这段代码使用了乐傻驴用户的代码,在此表示感谢;然后使用过滤器将原有的请求替换;
@ component 公开课UserInfoFilter扩展> @ component 公共类UserInfoInterceptor实现HandlerInterceptor { @Override 公共布尔preHandle (HttpServletRequest请求,HttpServletResponse响应对象处理程序){ 方法方法=((HandlerMethod)处理程序).getMethod (); AdminUserInfo AdminUserInfo=method.getDeclaredAnnotation (AdminUserInfo.class); 如果(adminUserInfo !=null) {//获取用户信息的逻辑自由发挥 长userId=((管理)((OAuth3Authentication) request.getUserPrincipal ()) .getPrincipal ()) .getId ();//将用户信息写入请求的参数 ((UserInfoRequest)请求)。addParameter(“标识”,userId); 返回true; } EmployeeUserInfo EmployeeUserInfo=method.getDeclaredAnnotation (EmployeeUserInfo.class); 如果(employeeUserInfo !=null) { 长userId=((员工)((OAuth3Authentication) request.getUserPrincipal ()) .getPrincipal ()) .getId (); ((UserInfoRequest)请求)。addParameter(“标识”,userId); 返回true; } 返回true; } }
上面我自己写了两个注解,这两个注解的代码我就不贴出来了,写这两个注解完全就是为了注入不同的用户信息;大家可以各自发挥,注解不是必须的,如果大家系统里面只有一种用户或者由于其他原因可以直接注入参数;接下来配置拦截