shiro拦截认证的全过程记录

目录
  • 概述
  • shrio 拦截认证全过程
  • 总结

概述

Shiro是apache旗下一个开源安全框架(http://shiro.apache.org/),它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。

Shiro框架三大核心对象

说明:

1)Subject :主体对象,负责提交用户认证和授权信息。

2)SecurityManager:安全管理器,负责认证,授权等业务实现。(核心)

3)Realm:领域对象,负责从数据层获取业务数据。

shrio 拦截认证全过程

 1.FilterRegistrationBean过滤注册bean

@Bean
public FilterRegistrationBean shiroFilterRegistration() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
    //该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
    registration.addInitParameter("targetFilterLifecycle", "true");
    registration.setEnabled(true);
    registration.setOrder(Integer.MAX_VALUE - 1);
    registration.addUrlPatterns("/*");
    return registration;
}

设置过滤的bean

2.shiroFilter 实际过滤配置bean

@Bean("shiroFilter")
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
    shiroFilter.setSecurityManager(securityManager);

    //oauth过滤
    Map<String, Filter> filters = new HashMap<>(10);
    filters.put("oauth2", new Oauth2Filter());
    shiroFilter.setFilters(filters);

    Map<String, String> filterMap = new LinkedHashMap<>();
    filterMap.put("/webjars/**", "anon");
    filterMap.put("/druid/**", "anon");
    filterMap.put("/login", "anon");

    filterMap.put("/**", "oauth2");
    shiroFilter.setFilterChainDefinitionMap(filterMap);

    return shiroFilter;
}

配置oauth2Filter为过滤类 过滤对象处/webjars/** /druid/** /login 外的所有

3.过滤类Oauth2Filter 继承 AuthenTicationFilter 重写以下方法

/**
 * 验证是否有效token
 * @param request re
 * @param response res
 * @return 验证token
 * @throws Exception
 */
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
    //获取请求token,如果token不存在,直接返回401
    String token = getRequestToken((HttpServletRequest) request);
    if(StringUtils.isBlank(token)){
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setContentType("application/json;charset=utf-8");
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());

        String json = new Gson().toJson(new Result().error(ErrorCode.UNAUTHORIZED));

        httpResponse.getWriter().print(json);

        return false;
    }

    return executeLogin(request, response);
}

4.调用父类 executeLogin 进行登录验证

protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
    AuthenticationToken token = this.createToken(request, response);
    if (token == null) {
        String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken must be created in order to execute a login attempt.";
        throw new IllegalStateException(msg);
    } else {
        try {
            Subject subject = this.getSubject(request, response);
            subject.login(token);
            return this.onLoginSuccess(token, subject, request, response);
        } catch (AuthenticationException var5) {
            return this.onLoginFailure(token, var5, request, response);
        }
    }
}

5.subject.login(token); 进行登录

login方法被DelegatingSubject重写

public void login(AuthenticationToken token) throws AuthenticationException {
    **
    Subject subject = this.securityManager.login(this, token);
    **
}

6.securityManager.login(this, token) login被DefaultSecurityManager

接下来几步没那么重要省略部分

7.ModularRealmAuthenticator AuthenticationInfo 授权信息获取方法

protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
    this.assertRealmsConfigured();
    Collection<Realm> realms = this.getRealms();
    return realms.size() == 1 ? this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken) : this.doMultiRealmAuthentication(realms, authenticationToken);
}

getRealms 获取我们自己重写的Realms类,主要用户获取用户信息

8.接下来则进入我们自己写的Realms类 我的类叫Oauth2Realm

/**
 * 认证(登录时调用)
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    String accessToken = (String) token.getPrincipal();

    //根据accessToken,查询用户信息
    SysUserTokenEntity tokenEntity = shiroService.getByToken(accessToken);
    //token失效
    if(tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()){
        throw new IncorrectCredentialsException(MessageUtils.getMessage(ErrorCode.TOKEN_INVALID));
    }

    //查询用户信息
    SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId());

    //转换成UserDetail对象
    UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class);

    //获取用户对应的部门数据权限
    List<Long> deptIdList = shiroService.getDataScopeList(userDetail.getId());
    userDetail.setDeptIdList(deptIdList);

    //账号锁定
    if(userDetail.getStatus() == 0){
        throw new LockedAccountException(MessageUtils.getMessage(ErrorCode.ACCOUNT_LOCK));
    }

    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDetail, accessToken, getName());
    return info;
}

负责获取用户信息的方法

这并不是登录的过程,而是授权过滤的过程,通过token到数据库查询是否有这个用户,且没有过期,则证明已经登录。

总结

到此这篇关于shrio拦截认证的文章就介绍到这了,更多相关shrio拦截认证内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解shrio的认证(登录)过程

    shrio是一个比较轻量级的安全框架,主要的作用是在后端承担认证和授权的工作.今天就讲一下shrio进行认证的一个过程. 首先先介绍一下在认证过程中的几个关键的对象: Subject:主体 访问系统的用户,主体可以是用户.程序等,进行认证的都称为主体: Principal:身份信息 是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名.手机号.邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal). credential:凭证信息 是只

  • shiro拦截认证的全过程记录

    目录 概述 shrio 拦截认证全过程 总结 概述 Shiro是apache旗下一个开源安全框架(http://shiro.apache.org/),它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权.加密.会话管理等功能,组成了一个通用的安全认证框架.使用shiro就可以非常快速的完成认证.授权等功能的开发,降低系统成本. Shiro框架三大核心对象 说明: 1)Subject :主体对象,负责提交用户认证和授权信息. 2)SecurityManager:安全管理器,负责认证

  • 使用Spring MVC拦截器实现日志记录的方法

    最近在研究Spring MVC拦截器,那么今天也算个学习笔记吧!有需要了解使用Spring MVC拦截器实现日志记录的朋友可参考.希望此文章对各位有所帮助. 1.  定义一个类实现HandlerInterceptor,比如: public class MyInterceptors implements HandlerInterceptor{ /** * 在渲染视图之后被调用: * 可以用来释放资源 */ public void afterCompletion(HttpServletRequest

  • spring security自定义认证登录的全过程记录

    spring security使用分类: 如何使用spring security,相信百度过的都知道,总共有四种用法,从简到深为: 1.不用数据库,全部数据写在配置文件,这个也是官方文档里面的demo: 2.使用数据库,根据spring security默认实现代码设计数据库,也就是说数据库已经固定了,这种方法不灵活,而且那个数据库设计得很简陋,实用性差: 3.spring security和Acegi不同,它不能修改默认filter了,但支持插入filter,所以根据这个,我们可以插入自己的f

  • spring整合shiro框架的实现步骤记录

    shiro Shiro是Apache下的一个开源项目,我们称之为Apache Shiro.它是一个很易用与Java项目的的安全框架,提供了认证.授权.加密.会话管理,与spring Security 一样都是做一个权限的安全框架,但是与Spring Security 相比,在于 Shiro 使用了比较简单易懂易于使用的授权方式.shiro属于轻量级框架,相对于security简单的多,也没有security那么复杂.更多详细的介绍可以从它的官网上(http://shiro.apache.org/

  • iOS动态更换Icon的全过程记录

    iOS 动态更换Icon 动态切换 App 的 icon 这个需求,在上一家公司做一款定制 App 时遇到过一次,这次领导说可能需要做,就又做了一次.虽然不是什么很难的知识点,这里也就记录一下自己做的过程吧. info.plist 文件编辑 更换 Icon 静默切换 info.plist 文件 为了动态更换 icon,我们需要先配置一下我们项目的 info.plist 文件: 1.加入 Icon files(iOS5),其中会默认有两个 item: Newsstand Icon Primary

  • 配置hive元数据到Mysql中的全过程记录

    在hive的安装目录下,进入conf目录,创建一个hive-site.xml文件 根据官方文档配置参数,拷贝数据到hive-site.xml文件中 https://cwiki.apache.org/confluence/display/Hive/AdminManual+MetastoreAdmin 注意:先创建一个metastore数据库,字符集要用latin1 将mysql驱动复制到hive的lib目录里.(这有关上一篇安装MySQL的内容) 解压驱动包 将mysql驱动复制到hive的lib

  • jdk15的安装与配置全过程记录

    如何下载并配置JDK 15 进入官网下载JDK 15. 官网地址:https://www.oracle.com/index.html 我们下载:https://www.jb51.net/softs/745289.html 1.点击Products然后点击java. 2.向下拉并找到 -Oracle JDK,点击进入. 3.点击下载JDK 15 我的电脑是win10,所以下载的win10的.推荐下载压缩版的.zip,好装也好卸载,也可以下载.exe直接下一步下一步,记得自己的安装路径就好. 点击下

  • C语言实现扫雷小游戏的全过程记录

    第一步思考要实现的功能 想必大家都知道扫雷这个小游戏,今天我们来用C语言实现一下,首先要扫雷,我们首先就需要有一个布置了雷的棋盘,然后开始扫雷,玩过扫雷的小伙伴都知道,如果选中的格子旁边没有雷,那么旁边的格子就会自动清空,大概的思路有了,现在我们开始实现. 第二步实现 初级版扫雷 首先创建棋盘的作用是用来存储雷的信息,这时我们思考一下,一个棋盘到底够不够用?棋盘多大才合适?我们打印出来的棋盘肯定是不能出现雷的信息的,不然游戏就无法正常进行了,但是我们雷的信息又需要棋盘存储,这样一想,一个棋盘似乎

  • 微信小程序引入Vant框架的全过程记录

    前言 有时候会觉得微信小程序原生的ui差了那么一点点感觉,那么能不能引入三方框架呢?本文以引入Vant来进行举例,共包含8个步骤.不管是不是云开发项目都一样使用. 实现步骤 1. 打开微信小程序的开发工具,进入项目.在项目的根目录文件上点击右键.选择在终端中打开.(注意是根目录) 2. 在命令窗口中键入npm init.然后所有配置都按默认配置进行,只需点击回车键即可. 3. 在命令窗口中键入npm install进行构建,成功之后会在根目录下生成 package.json 和 package-

  • vue3递归组件封装的全过程记录

    目录 前言 1.递归组件 2.右键菜单组件 总结 前言 今天在写项目时,遇到一个自定义右键菜单的需求.在菜单中还有子菜单,所以这个时候就要用到递归组件了.所以写下这篇文章来记录一下自己编写递归组件的过程. 1.递归组件    递归组件,顾名思义就是在组件本身内部调用自身.所以我们先构建一个组件,并在自身内部调用自身.常见的递归组件就是我们项目中经常会用到的树组件了.下面就是我自己实现的一个能够满足项目需求的递归组件的源码. <template> <ul class="list-

随机推荐