一、引入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. python Tkinter的Text组件中创建x轴和y轴滚动条

    #!/usr/bin/python #coding: utf-8 from Tkinter import * root = Tk() root.title("记事本") root. ...

  2. Pycharm激活方法使用的是(license server)

    pycharm所有版本 http://www.jetbrains.com/pycharm/download/previous.html打开激活窗口 选择 Activate new license wi ...

  3. http协议 | http缓存

    缓存控制 1.禁止进行缓存:缓存中不得存储任何关于客户端请求和服务端响应的内容.每次由客户端发起的请求都会下载完整的响应内容. Cache-Control: no-store Cache-Contro ...

  4. placeholder 效果的实现,input提示字,获取焦点时消失

    <!doctype html><html><head><meta charset="utf-8"><title>plac ...

  5. linux修改镜像

    修改为163yum源-mirrors.163.com 1.首先备份系统自带yum源配置文件/etc/yum.repos.d/CentOS-Base.repo [root@localhost ~]# m ...

  6. LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays

    原题链接在这里:https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/ 题目: In a given arr ...

  7. 未能找到 System.Web.Helpers

    This question is a bit old but here's a simple solution - Microsoft seemed to just move this library ...

  8. 比较两个CSV的方法的探索

    1.开始时,我用ultraEdit来简单比较,需要排序,而且比较的结果也有限 2.Excel也有这样的功能,可是好复杂 3.而后,发现dbeaver这个tools,利用JDBC Driver(csvj ...

  9. python函数 | 生成器

    生成器本质上是迭代器,包含__iter__和__next__功能 生成器的产生方式: 1,生成器函数构造. 2,生成器推导式构造. 3,数据类型的转化. 通过构造生成器函数,就是将函数中的return ...

  10. thymeleaf做if判定

    <div class="showing"> <h2>条件判断</h2> <p th:if="${testBoolean}&quo ...