一、引入maven配置

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.0</version>
</dependency>

二、建表

用户表、角色表、权限表、用户角色表、角色权限表。

用户表:

角色表:

权限表:news:* 表示有新闻的所有权限(包括增删改查),而news:add,只有新闻的新增权限。

用户角色表:用户拥有哪些角色。

角色权限表:角色拥有哪些权限。

三、自定义Realm

自定义realm主要用于用户的权限验证以及登录验证。

自定义realm继承AuthorizingRealm类,并重写doGetAuthorizationInfo和doGetAuthenticationInfo方法,doGetAuthorizationInfo方法主要校验用户的权限,即该用户拥有什么角色以及权限。doGetAuthenticationInfo用于校验登录验证,即用户的用户名或者密码是否正确。

/**
 * 类名 : shiro的Realm
 * 用法 :
 * 创建人 : shyroke
 * 时间:2018/12/12 17:29
 */
public class MyRealm extends AuthorizingRealm {     @Autowired
    private UserMapper userMapper;     @Autowired
    private PermissionMapper permissionMapper;     /**
     * 授权,即该用户拥有什么角色以及权限
     * 步骤:根据用户名获取角色以及权限,然后设置到验证信息类并返回。
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();         String userName = principalCollection.getPrimaryPrincipal().toString(); //        获取该用户的角色
        List<Role> roles = userMapper.getRolesByUserName(userName);
        Set<String> roleSets = new HashSet<>(); //        获取该用户的权限集
        List<Permission> permissions = new ArrayList<>();
        Set<String> permissoinSet = new HashSet<>();         //将List转为Set
        if(roles !=null && roles.size()>0){
            for(Role role:roles){
                roleSets.add(role.getName());
                permissions.addAll(permissionMapper.getPermissionByRoleId(role.getId()));
            }
        }         //将List转为Set
        if(permissions!=null & permissoinSet.size()>0){
            for(Permission p :permissions){
                permissoinSet.add(p.getName());
            }
        }         info.addRoles(roleSets);
        info.addStringPermissions(permissoinSet);         return info;
    }     /**
     * 认证,即用户账号密码是否正确
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//        获取用户名和密码
        String userName = (String)token.getPrincipal();
        String passWord = new String((char[]) token.getCredentials()); //        根据用户名查找该用户
        User user =  userMapper.getUserByName(userName);         if(user == null){
            throw new UnknownAccountException("用户名不存在");
        }         if(!user.getPassword().equals(passWord)){
            throw new IncorrectCredentialsException("密码错误");
        }         SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getName(),user.getPassword(),getName());         return info;
    }
}

四、shiro配置类

/**
 * 类名 :shiro的核心配置类
 * 用法 :
 * 创建人 : shyroke
 * 时间:2018/12/14 15:20
 */
@Configuration
public class ShiroConfigration { //    设置自定义Realm
    @Bean
    public MyRealm myRealm(){
        return new MyRealm();
    } //    权限管理,配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(myRealm());
        return manager;
    }     /**
     * 设置过滤条件和跳转条件
     * anon 不生效的原因:1、map的类型必须是LinkedHashMap 2、anon必须定义在authc之前
     *
     * @param securityManager
     * @return
     */
    @Bean
        public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
            ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
            factoryBean.setSecurityManager(securityManager); //            设置登录跳转
            factoryBean.setLoginUrl("/admin");
            factoryBean.setSuccessUrl("/admin/index");             //必须为LinkedHashMap 否则anon不生效
            Map<String,String> map = new LinkedHashMap<>();             //退出
            map.put("/admin/logout","logout");             //登录页面和登录验证不要拦截
            map.put("/admin/login.html","anon");
            map.put("/admin/tologin","anon");             //设置需要过滤的链接
            map.put("/admin/**","authc");             factoryBean.setFilterChainDefinitionMap(map);             return factoryBean;
        }     /**
     *  开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此功能
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }     /**
     * 开启aop注解支持
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    } }

五、调用

代码如下,当调用Subject.login方法后,会调用自定义Realm的doGetAuthenticationInfo方法校验用户名密码是否正确,如果不正确则抛出对应异常,controller层捕获并处理异常。

AuthenticationToken usernamePasswordToken = new UsernamePasswordToken(user.getName(),user.getPassword());

Subject subject = SecurityUtils.getSubject();

try {
    subject.login(usernamePasswordToken);
}catch (UnknownAccountException ex) {
    logger.info("用户名错误!");
    return R.error("用户名错误!");
} catch (IncorrectCredentialsException ex) {
    logger.info("密码错误!");
    return R.error("密码错误!");
} catch (AuthenticationException ex) {
    logger.info(ex.getMessage());
    return R.error("系统错误,请查看日志");
} catch (Exception ex) {
    logger.info(ex.getMessage());
    return R.error("系统错误,请查看日志");
}

(十二)springboot中shiro的使用的更多相关文章

  1. (转)SpringMVC学习(十二)——SpringMVC中的拦截器

    http://blog.csdn.net/yerenyuan_pku/article/details/72567761 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter, ...

  2. OpenJDK源码研究笔记(十二):JDBC中的元数据,数据库元数据(DatabaseMetaData),参数元数据(ParameterMetaData),结果集元数据(ResultSetMetaDa

    元数据最本质.最抽象的定义为:data about data (关于数据的数据).它是一种广泛存在的现象,在许多领域有其具体的定义和应用. JDBC中的元数据,有数据库元数据(DatabaseMeta ...

  3. SpringBoot中Shiro缓存使用Redis、Ehcache

    在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...

  4. SpringBoot中Shiro使用Pac4j集成CAS认证

    SpringBoot中Shiro使用Pac4j集成CAS认证 Pac4j 简介 Pac4j与Shiro,Spring Security一样都是权限框架,并且提供了OAuth - SAML - CAS ...

  5. springboot系列(十)springboot整合shiro实现登录认证

    关于shiro的概念和知识本篇不做详细介绍,但是shiro的概念还是需要做做功课的要不无法理解它的运作原理就无法理解使用shiro: 本篇主要讲解如何使用shiro实现登录认证,下篇讲解使用shiro ...

  6. (十二)整合 Shiro 框架,实现用户权限管理

    整合 Shiro 框架,实现用户权限管理 1.Shiro简介 1.1 基础概念 1.2 核心角色 1.3 核心理念 2.SpringBoot整合Shiro 2.1 核心依赖 2.2 Shiro核心配置 ...

  7. [十二]SpringBoot 之 servlet

    Web开发使用 Controller 基本上可以完成大部分需求,但是我们还可能会用到 Servlet.Filter.Listener.Interceptor 等等. 当使用spring-Boot时,嵌 ...

  8. 十二.spring-boot使用spring-boot-freemarker

    ①.在springMVC中:它代表着view层组件 ②.为什么使用freemarker:简单容易学.逻辑分明 ③.freemarker优点:它不依赖servlet.网络或者web环境 一.创建一个ma ...

  9. Expo大作战(十二)--expo中的自定义样式Custom font,以及expo中的路由Route&Navigation

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

随机推荐

  1. Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'org_mer_id' in where clause is ambiguous

    ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolatio ...

  2. combineReducers(reducers)

    combineReducers(reducers) 随着应用变得越来越复杂,可以考虑将 reducer 函数 拆分成多个单独的函数,拆分后的每个函数负责独立管理 state 的一部分. combine ...

  3. spring:过滤器和拦截器

    过滤器:网络通信模型的会话层控制: 拦截器:事务处理的aop注入(生命周期监控). 对于Servlet Filter,官方文档中说的很好, 并且给出了常见的应用场景. A filter is an o ...

  4. ES6学习笔记--属性名表达式

    1.直接用标识符作为属性名: obj.foo = true 2.用表达式作为属性名: obj['a'+'bc'] = 123 //相当于 obj['abc'] = 123 3.ES6 允许字面量定义对 ...

  5. python语言(二)列表、字典、集合、文件读写、关系测试

    1.列表 list   代码 s = '王宇建,苏红,邹存才...' # 列表 数字 list l = ['王宇建','苏红','邹存才'] # 一维数组 二维数组 三维数组 # 0 1 2 # 索引 ...

  6. CLR Exception---E0434352

    什么是CLR Exception---E0434352 CLR异常是.NET应用程序生成的异常类型.异常被封装在从System.exception类派生的类中.它的异常代码是0xE0434352,代码 ...

  7. 使用Windows事件查看器调试崩溃

    本文讨论如何使用Windows事件查看器获取实际崩溃的模块以及代码中崩溃的位置.示例代码是用C++编写的,以生成不同类型的崩溃,例如访问冲突和堆栈溢出. 简介 我经常听同事和QA那里听说,一个特定的崩 ...

  8. 为知笔记docker 版本运行

    最近为知提供了服务端的docker 运行,因为是全家桶,镜像偏大,但是使用还很不错,对于少于5人的可以免费使用 docker-compose 文件 version: "3" ser ...

  9. TCP三次握手的过程,accept发生在三次握手的哪一个阶段?

    答案是:accept过程发生在三次握手之后,三次握手完成后,客户端和服务器就建立了tcp连接并可以进行数据交互了.这时可以调用accept函数获得此连接. TCP Accept总结 TCP Accep ...

  10. 洛谷p2370yyy2015c01的U盘题解

    没什么特殊的想法 就是看自己很久没有更新关于题解类的文章了而已 (其实这是我好久之前做的, 只是把它从洛谷博客搬到了这里而已) 题目 首先分析题目要二分 他长成这个亚子太二分了 所以就要二分 最好是先 ...