跟着我的步骤:先运行起来再说

Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc


一:导包

        <!-- Shiro安全框架 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>

二:ShiroConfig配置


import cn.zyzpp.shiro.CustomRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Create by yster@foxmail.com 2018/5/17/017 20:18
 */
@Configuration
public class ShiroConfig {
    /**
     * 记住我:自动登录-1
     */
    @Bean
    public SimpleCookie getSimpleCookie(){
        SimpleCookie simpleCookie = new SimpleCookie();
        simpleCookie.setName("rememberMe");
        simpleCookie.setMaxAge(20000000);
        return simpleCookie;
    }

    /**
     * 记住我:自动登录-2
     */
    @Bean
    public CookieRememberMeManager getCookieRememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(getSimpleCookie());
        return cookieRememberMeManager;
    }

    /**
     * 开启MD5加密
     * @return
     */
    @Bean
    public HashedCredentialsMatcher getMatcher(){
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("md5");
        matcher.setHashIterations(1);
        return matcher;
    }

    /**
     * 自定义Realm密码验证与加密
     * @return
     */
    @Bean
    public CustomRealm getCustomRealm(){
      CustomRealm customRealm = new CustomRealm();
      customRealm.setCredentialsMatcher(getMatcher());
      return customRealm;
    }

    /**
     * 创建SecurityManager环境
     * @return
     */
    @Bean
    public DefaultWebSecurityManager getSecurityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(getCustomRealm());
        securityManager.setRememberMeManager(getCookieRememberMeManager());
        return securityManager;
    }

    /**
     * Shiro在Web项目中的过滤
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean getfilterFactoryBean(){
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        filterFactoryBean.setSecurityManager(getSecurityManager());
        /**
         *  只有在下面配置路径访问权限,Shiro才会执行自动跳转。
         *  如果使用Shiro注解权限,就只会报异常,
         *  就只能采用统一异常处理的方法。
         */
        //拦截器.
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/static/**", "anon");
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/user/exit", "logout");
        //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/user/user", "authc");
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        filterFactoryBean.setLoginUrl("/user/login");
        // 登录成功后要跳转的链接
        filterFactoryBean.setSuccessUrl("/");
        //未授权界面;
        filterFactoryBean.setUnauthorizedUrl("/user/login");
        filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return filterFactoryBean;
    }

    /**
     * 保证Shiro的声明周期
     * @return
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 开启Shiro授权生效
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
        return new AuthorizationAttributeSourceAdvisor();
    }

}

三:自定义授权类

import cn.zyzpp.service.user.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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import java.util.Set;

/**
 * Create by yster@foxmail.com 2018/5/17/017 20:38
 */
public class CustomRealm extends AuthorizingRealm {

    private String ClassName =this.getClass().getName();

    @Autowired
    @Lazy   //必须懒加载,否则Ehcache缓存注解及事务管理注解无效
    private UserService userService;

    {
        super.setName(ClassName);
    }

    /**
     * 权限处理
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        // 从数据库或者缓存中获得角色数据
        Set<String> roles = userService.getRolesByUserName(username);
        Set<String> permissions = userService.getPermissionsByRoles(roles);
        //上面的service层方法需要自己写
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setStringPermissions(permissions);
        simpleAuthorizationInfo.setRoles(roles);

        return simpleAuthorizationInfo;
    }

    /**
     * 认证处理
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 1.从主体传过来的认证信息中,获得用户名
        String username = (String) token.getPrincipal();

        // 2.通过用户名到数据库中获取凭证
        String password = userService.getPasswordByUsername(username);
        if(password == null) {
            return null;
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, ClassName);
        return simpleAuthenticationInfo;
    }

}

四:使用

1)登录验证:

    @RequestMapping(value = "/login/result", method = RequestMethod.POST)
    public String userLogin(User user) {
        String error = null;
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getMail(), user.getPassword());
        try {
            token.setRememberMe(user.isRememberMe());//记住我
            subject.login(token);
        } catch (UnknownAccountException e) {
            error = "用户名/密码错误";
        } catch (IncorrectCredentialsException e) {
            error = "用户名/密码错误";
        } catch (AuthenticationException e) {
            //其他错误,比如锁定,如果想单独处理请单独catch处理
            error = "其他错误:" + e.getMessage();
        }
        if(error != null) {//出错了,返回登录页面

        } else {//登录成功

        }
    }

2)权限验证:

  • 可以在配置文件中配置Url权限等,参考步骤二。

  • 使用诸如 @RequiresRoles(“user”) 注解在controller层的方法上,进行角色验证,或者使用@RequiresPermissions(“index:hello”)进行权限验证,不过使用注解Shiro就只抛出异常,无法使用shiro设置自动跳转到页面等。针对这个问题,可以用@ControllerAdvice统一异常处理。

    @RequiresRoles("user")
    @RequestMapping(value = "/up")
    public String up(){

    }

本实例旨在讲解SpringBoot集成,Shiro教程推荐:http://wiki.jikexueyuan.com/project/shiro/

SpringBoot集成Shiro安全框架的更多相关文章

  1. SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架

    SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...

  2. 在前后端分离的SpringBoot项目中集成Shiro权限框架

    参考[1].在前后端分离的SpringBoot项目中集成Shiro权限框架 参考[2]. Springboot + Vue + shiro 实现前后端分离.权限控制   以及跨域的问题也有涉及

  3. SpringBoot集成Shiro并用MongoDB做Session存储

    之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...

  4. springboot集成shiro实现权限认证

    github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...

  5. Springboot整合Shiro安全框架

    最近在学习Springboot,在这个过程中遇到了很多之前都没有技术知识,学习了一阵子,稍微总结一些. ---- Shiro框架 shiro框架,是一个相对比较简便的安全框架,它可以干净利落地处理身份 ...

  6. SpringBoot集成Shiro 实现动态加载权限

    一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...

  7. springboot集成shiro 实现权限控制(转)

    shiro apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自 ...

  8. SpringBoot集成Shiro实现权限控制

    Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...

  9. 【Shiro】SpringBoot集成Shiro

    项目版本: springboot2.x shiro:1.3.2 Maven配置: <dependency> <groupId>org.apache.shiro</grou ...

随机推荐

  1. leetcode-217存在重复元素

    leetcode-217存在重复元素 题意 给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: ...

  2. Android 内存管理中的 Shallow heap Retained heap

    所有包含Heap Profling功能的工具(MAT,Yourkit,JProfiler,TPTP等)都会使用到两个名词,一个是Shallow heap Size,另一个是 Retained heap ...

  3. LeetCode题解之Binary Tree Right Side View

    1.题目描述 2.问题分析 使用层序遍历 3.代码 vector<int> v; vector<int> rightSideView(TreeNode* root) { if ...

  4. windows网络编程中文 笔记(二)

    IPv4 地址段 IPv4地址类别 种类 网络部分 第1个数字 端点数字 A  8位  0-127  16777216 B  16位  128-191  65526 C  24位  193-223   ...

  5. C#-方法(八)

    方法是什么 方法是C#中将一堆代码进行进行重用的机制 他是在类中实现一种特定功能的代码块,将重复性功能提取出来定义一个新的方法 这样可以提高代码的复用性,使编写程序更加快捷迅速 方法格式 访问修饰符 ...

  6. SQL2008无法附加数据库,提示“无法显示请求的对话框”(nColIndex实际值是-1)图文解决方法

    SQL2008无法附加数据库,提示“无法显示请求的对话框”(nColIndex实际值是-1)图文解决方法 SQL2008无法附加数据库,提示“无法显示请求的对话框”(nColIndex实际值是-1)图 ...

  7. java学习(权限修饰符)

    Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符.使用对象:类. ...

  8. JavaScript -- 时光流逝(十):Screen 对象、History 对象、Location 对象

    JavaScript -- 知识点回顾篇(十):Screen 对象.History 对象.Location 对象 1. Screen 对象 1.1 Screen 对象的属性 (1) availHeig ...

  9. June 8. 2018 Week Week 23rd Friday

    You'll have bad times, but it'll always wake you up to the good stuff you weren't paying attention t ...

  10. Linux常用命令-文本查看篇

    前言 Linux常用命令中,除了cat还有很多其他用于文本查看的命令.本文将简单介绍一下这些文本查看的命令. 全文本显示--cat cat可能是常用的一个文本查看命令了,使用方法也很简单: cat f ...