6、用户登陆controller实现
(1)当用户第一次到达登陆页面时,通过get方式。
@RequestMapping(value = "/login", method = RequestMethod.GET) public String login(@Param("phone") String phone, @Param("upwd") String upwd) { return "login"; }
(2)用户提交登陆信息时,通过post方法。
@RequestMapping(value = "/login", method = RequestMethod.POST) public ModelAndView login2(@Param("phone") String phone, @Param("upwd") String upwd) { ModelAndView m = new ModelAndView(); //添加用户认证信息 Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken uToken = new UsernamePasswordToken(phone, upwd); //实现记住我 uToken.setRememberMe(true); try { //进行验证,报错返回首页,不报错到达成功页面。 subject.login(uToken); } catch (UnknownAccountException e) { m.addObject("result", "用户不存在"); m.setViewName("login"); return m; } catch (IncorrectCredentialsException e) { m.addObject("result", "密码错误"); m.setViewName("login"); return m; } //将权限信息保存到session中 User user = sd.querybyname(phone); List<Permission> permissions = new ArrayList<Permission>(); for (Role role : user.getRoles()) { for (Permission permission : role.getPermissions()) { permissions.add(permission); } } Map<String, ArrayList<Permission>> map = new HashMap<String, ArrayList<Permission>>(); for (Permission p : permissions) { String name = p.getPermission_group_name(); if (!map.containsKey(name)) { ArrayList<Permission> mList = new ArrayList<Permission>(); mList.add(p); map.put(name, mList); } else { ArrayList<Permission> pList = map.get(name); pList.add(p); map.put(name, pList); } } // 保存到shiro的session中一些信息 Session session = subject.getSession(); // 保存userinfo的基本信息 int uid = user.getUid(); UserInfo userInfo = sd.queryuserinfo(uid); //保存user信息 session.setAttribute("user", user); //shiro权限验证成功后跳转的界面 m.setViewName("index"); return m; }
7、用户前端登录页面
(1)部分代码
<div class="login-box-body"> <p class="login-box-msg">登录更精彩!!!</p> <form action="login" method="post"> <div class="form-group has-feedback"> <input type="phone" class="form-control" placeholder="请输入手机号" name="phone"> <span class="glyphicon glyphicon-envelope form-control-feedback"></span> </div> <div class="form-group has-feedback"> <input type="password" class="form-control" placeholder="请输入密码" name="upwd"> <span class="glyphicon glyphicon-lock form-control-feedback"></span> </div> <div class="row"> <div class="col-xs-8"> <div class="checkbox icheck"> <label> <input type="checkbox" name="rememberMe"> 记住账户 </label> </div> </div> <!-- /.col --> <div class="col-xs-4"> <button type="submit" class="btn btn-primary btn-block btn-flat">登录</button> <p th:text="${result}" style="color: red"></p> </div> <!-- /.col --> </div> </form> <!-- /.social-auth-links --> <a href="#">忘记密码?</a> <a href="/register" class="text-center">注册</a> </div> <!-- /.login-box-body --> </div>
(2)页面展示
8、前台使用shiro结合thymeleaf实现细粒度权限具体实现
<div class="description-block"> <shiro:hasAnyRoles name="教员"> <h5 class="description-header" th:text="${courses.size()}">35</h5> </shiro:hasAnyRoles> <shiro:hasAnyRoles name="管理员"> <h5 class="description-header" >0</h5> </shiro:hasAnyRoles> <shiro:hasAnyRoles name="普通用户"> <h5 class="description-header" >0</h5> </shiro:hasAnyRoles> <span class="description-text">课程数</span> </div>
三、注意事项
1、记住我功能
(1)我们自定义记住我过滤器是为了在通过isRemember()登录时,能够得到和通过isAuthenticated()登录一样的信息,因为当我们通过isAuthenticated()登录时,我们获取了一下session信息,通过isRemember()登陆我们只拿到了账户密码信息,虽然能够登陆成功,但是由于缺少一些session信息,在到达首页时会报错,完成不了后续的操作。
(2)在shiroConfig中我们需要配置自定义的过滤器,并在该类的shiro全局配置中把该过滤器注入进来,让其功能实现。
Map<String, Filter> filterMap=new LinkedHashMap<String,Filter>(); filterMap.put("MyRememberFilter",MyRememberFilter());
(3)我们需要把shiroConfig全局配置中的下面的权限改为user权限
linkedHashMap.put("/**", "authc");
如果我们使用authc权限,我们通过记住我登陆成功后,关闭浏览器,再打开还是需要输入账户密码,不能直接到达首页,没有实现效果,因为isRemember()的权限是user权限,比authc权限低,所以通过记住我登陆后,shiro会觉得不安全,让再次输入密码,只有改为user权限才能实现,下次打开浏览器,不需要输入密码,直接登陆成功。
(4)但是使用user权限又会带来新的问题,我们对一些敏感的信息,不想让用户通过user权限看到,这时需要对此种页面使用authc权限,当到达这样的页面时,我们需要账户密码重新登陆一下。
2、密码加密功能
(1)我们必须在MyMathcher中对拿到的前台的密码进行加密后再与数据库中的密码进行比对。
(2)在注册时,我们需要用相同的加密算法对用户注册的密码进行加密保存的数据库中,通过shiro验证时,拿加密后的数据库中的密码与前台用户登录时的密码加密后进行比对。这样才能够实现权限验证。
(3)我只是使用了一种简单的算法,大家可以用加盐的MD5,自行操作。