SSM(三)Shiro 使用详解(上)

简介: 相比有做过企业级开发的童鞋应该都有做过权限安全之类的功能吧,最先开始我采用的是建用户表,角色表,权限表,之后在拦截器中对每一个请求进行拦截,再到数据库中进行查询看当前用户是否有该权限,这样的设计能满足大多数中小型系统的需求。不过这篇所介绍的Shiro能满足之前的所有需求,并且使用简单,安全性高,而且现在越来越的多企业都在使用Shiro,这应该是一个收入的你的技能库。

创建自定义MyRealm


有关Shiro的基础知识我这里就不过多介绍了,直接来干货,到最后会整合Spring来进行权限验证。


首先在使用Shiro的时候我们要考虑在什么样的环境下使用:


基本上我们也就这三个需求,所以同时我们也需要三个方法:


  1. findUserByUserName(String username)根据username查询用户,之后Shiro会根据查询出来的User的密码来和提交上来的密码进行比对。


  1. findRoles(String username)根据username查询该用户的所有角色,用于角色验证。


  1. findPermissions(String username)根据username查询他所拥有的权限信息,用于权限判断。


下面我贴一下我的mapper代码(PS:该项目依然是基于之前的SSM,不太清楚整合的请看SSM一)。


id, username, password,roleId
        select 
        from t_user where userName=#{userName}
        select r.roleName from t_user u,t_role r where u.roleId=r.id and u.userName=#{userName}
        select p.permissionName from t_user u,t_role r,t_permission p
        where u.roleId=r.id and p.roleId=r.id and u.userName=#{userName}


很简单只有三个方法,分别对应上面所说的三个方法。对sql稍微熟悉点的童鞋应该都能看懂,不太清楚就拷到数据库中执行一下就行了,数据库的Sql也在我的github上。实体类就比较简单了,就只有四个字段以及get,set方法。我就这里就不贴了,具体可以去githubfork我的源码。


现在就需要创建自定义的MyRealm类,这个还是比较重要的。继承至ShiroAuthorizingRealm类,用于处理自己的验证逻辑,下面贴一下我的代码:


package com.crossoverJie.shiro;
import com.crossoverJie.pojo.T_user;
import com.crossoverJie.service.T_userService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import javax.annotation.Resource;
import java.util.Set;
/**
 * Created with IDEA
 * Created by ${jie.chen} on 2016/7/14.
 * Shiro自定义域
 */
public class MyRealm extends AuthorizingRealm {
    @Resource
    private T_userService t_userService;
    /**
     * 用于的权限的认证。
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = principalCollection.getPrimaryPrincipal().toString() ;
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo() ;
        Set roleName = t_userService.findRoles(username) ;
        Set permissions = t_userService.findPermissions(username) ;
        info.setRoles(roleName);
        info.setStringPermissions(permissions);
        return info;
    }
    /**
     * 首先执行这个登录验证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        //获取用户账号
        String username = token.getPrincipal().toString() ;
        T_user user = t_userService.findUserByUsername(username) ;
        if (user != null){
            //将查询到的用户账号和密码存放到 authenticationInfo用于后面的权限判断。第三个参数传入realName。
            AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),
                    "a") ;
            return authenticationInfo ;
        }else{
            return  null ;
        }
    }
}


继承AuthorizingRealm类之后就需要覆写它的两个方法,doGetAuthorizationInfo,doGetAuthenticationInfo,这两个方法的作用我都有写注释,逻辑也比较简单。


doGetAuthenticationInfo是用于登录验证的,在登录的时候需要将数据封装到Shiro的一个token中,执行shiro的login()方法,之后只要我们将MyRealm这个类配置到Spring中,登录的时候Shiro就会自动的调用doGetAuthenticationInfo()方法进行验证。


哦对了,忘了贴下登录的Controller了:


package com.crossoverJie.controller;
import com.crossoverJie.pojo.T_user;
import com.crossoverJie.service.T_userService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
/**
 * Created with IDEA
 * Created by ${jie.chen} on 2016/7/14.
 * 后台Controller
 */
@Controller
@RequestMapping("/")
public class T_userController {
    @Resource
    private T_userService t_userService ;
    @RequestMapping("/loginAdmin")
    public String login(T_user user, Model model){
        Subject subject = SecurityUtils.getSubject() ;
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(),user.getPassword()) ;
        try {
            subject.login(token);
            return "admin" ;
        }catch (Exception e){
            //这里将异常打印关闭是因为如果登录失败的话会自动抛异常
//            e.printStackTrace();
            model.addAttribute("error","用户名或密码错误") ;
            return "../../login" ;
        }
    }
    @RequestMapping("/admin")
    public String admin(){
        return "admin";
    }
    @RequestMapping("/student")
    public String student(){
        return "admin" ;
    }
    @RequestMapping("/teacher")
    public String teacher(){
        return "admin" ;
    }
}


主要就是login()方法。逻辑比较简单,只是登录验证的时候不是像之前那样直接查询数据库然后返回是否有用户了,而是调用subjectlogin()方法,就是我上面提到的,调用login()方法时Shiro会自动调用我们自定义的MyRealm类中的doGetAuthenticationInfo()方法进行验证的,验证逻辑是先根据用户名查询用户,如果查询到的话再将查询到的用户名和密码放到SimpleAuthenticationInfo对象中,Shiro会自动根据用户输入的密码和查询到的密码进行匹配,如果匹配不上就会抛出异常,匹配上之后就会执行doGetAuthorizationInfo()进行相应的权限验证。


doGetAuthorizationInfo()方法的处理逻辑也比较简单,根据用户名获取到他所拥有的角色以及权限,然后赋值到SimpleAuthorizationInfo对象中即可,Shiro就会按照我们配置的XX角色对应XX权限来进行判断,这个配置在下面的整合中会讲到。


整合Spring


接下来应该是大家比较关系的一步:整合Spring


我是在之前的Spring SpringMVC Mybatis的基础上进行整合的。


相关文章
SSM如何整合Shiro实现权限登陆案例
SSM如何整合Shiro实现权限登陆案例
64 0
|
Java 数据安全/隐私保护
基于SSM+Shiro+Bootstrap实现用户权限管理系统
基于SSM+Shiro+Bootstrap实现用户权限管理系统
212 0
基于SSM+Shiro+Bootstrap实现用户权限管理系统
|
安全 前端开发 Java
SSM(三)Shiro 使用详解(下)
相比有做过企业级开发的童鞋应该都有做过权限安全之类的功能吧,最先开始我采用的是建用户表,角色表,权限表,之后在拦截器中对每一个请求进行拦截,再到数据库中进行查询看当前用户是否有该权限,这样的设计能满足大多数中小型系统的需求。不过这篇所介绍的Shiro能满足之前的所有需求,并且使用简单,安全性高,而且现在越来越的多企业都在使用Shiro,这应该是一个收入的你的技能库。
|
缓存 前端开发 数据库
SSM整合Shiro实现RBAC(八)下
SSM整合Shiro实现RBAC(八)
150 0
SSM整合Shiro实现RBAC(八)下
|
XML 前端开发 Java
SSM整合Shiro实现RBAC(八)上
SSM整合Shiro实现RBAC(八)
149 0
SSM整合Shiro实现RBAC(八)上
|
缓存 Java 数据安全/隐私保护
SSM整合Shiro实现RBAC(八)中
SSM整合Shiro实现RBAC(八)
|
JavaScript 前端开发 Java
基于vue(element ui) + ssm + shiro 的权限框架
随着前后端分离项目的热潮,前端各大框架的,前后端沟通部分也成了问题,之前服务端渲染的页面生成到前端来,现在前后端可能是两个服务器,一些技术的迁移,本框架的权限部分的设计思想,借鉴了前端大牛的想法,也有传统后端的设计方案,抛砖引玉,做个桥梁,实现前后端分离的权限的设计,代码仅供参考,思路仅供参考,相信优秀的你写自己的代码,用自己的思想会更为贴切,方便。
4719 0
|
数据安全/隐私保护 数据格式 XML
JavaWeb项目:Shiro实现简单的权限控制(整合SSM)
JavaWeb项目:Shiro实现简单的权限控制(整合SSM) 数据库表格相关设计 表格设计得比较简单,导航栏直接由角色表auth_role的角色描述vRoleDesc(父结点)和角色相关权限中的权限描述(标记为导航结点)vPermissionDesc(展开子项)组成。
4636 0
|
Java 应用服务中间件 数据库
分布式框架简介SSM组合+ springmvc+mybatis+shiro+restful+bootstrap
分布式框架简介SSM组合+ springmvc+mybatis+shiro+restful+bootstrap
5492 0
|
Web App开发 Java 测试技术
shiro与SSM项目整合
shiro于SSM整合所有的jar包 web.xml中配置shiro的filter 在web系统中,shiro也通过filter进行拦截。filter拦截后将操作权交给spring中配置的filterChain(过虑链儿) shiro提供很多filter。 applicationContext-shiro.xml 在applicationContext-
4180 0