Shiro+Mybatis实现登录认证、授权功能

一、实现登录认证功能

  • 1、流程:

    • 跟据用户提交表单的账号,经Mybatis框架在数据库中查出User对象:

      • 如果User为空,则会抛出异常:UnknownAccountException,没有此账户名。
      • 如果不为空,则比对表单中的密码和User对象的密码是否相同(shiro框架自动完成,有加密),密码不相同则会抛出异常:IncorrectCredentialsException,密码错误;密码相同,则登陆成功。
  • 2、详细流程:

    • 1)代码结构如图:

    • 2)RouterController类接收表单的请求后,将用户提交的表单数据封装成令牌,并执行方法 subjec.login(token)(用令牌登陆),下面是RouterController的部分代码

      @RequestMapping("/login")
      public String login(String usr, String pwd, Model model){ //获取当前用户
      Subject subject = SecurityUtils.getSubject(); //封装用户的登陆数据,生成令牌
      UsernamePasswordToken token = new UsernamePasswordToken(usr,pwd); //用令牌登陆,如果没有异常则登陆成功
      try{
      subject.login(token);
      //无异常则登陆成功
      return "index";
      }catch(UnknownAccountException e){
      model.addAttribute("msg","用户名错误");
      return "login";
      }catch(IncorrectCredentialsException e){
      model.addAttribute("msg","密码错误");
      return "login";
      }
      }
    • 3)subjec.login(token)会调用UserRealm的认证方法doGetAuthenticationInfo(AuthenticationToken aToken)(UserRealm中有两个方法,一个授权,一个认证),下面是UserRealm的部分代码(认证方法):

      //认证
      @Override
      protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //先取令牌
      UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; //根据令牌信息从数据库中取出用户
      User user = userService.getUserByEmail(token.getUsername());
      if(user==null){
      return null; //返回null,则抛出无用户名的异常
      } //验证密码,Shiro自动验证,只需要把数据库的密码传过去就好了
      return new SimpleAuthenticationInfo(user,user.getPassword(),"");
      }

二、实现授权功能

  • 1、给请求设置权限,下面是ShiroConfig三病(Bean)的第一个病(Bean)ShiroFilterFactoryBean,主要负责给各种请求设置各种权限,只有拥有权限的用户才可访问请求

    @Bean	//此注解意思就是在程序开始运行前,会自动给spring托管
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
    ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
    //关联securityManager
    bean.setSecurityManager(securityManager); //给请求设置权限
    Map<String,String> filter = new LinkedHashMap<>();
    filter.put("/user/information","perms[user:gr]"); //有权限"user:gr"才可访问
    filter.put("/user/recommend","perms[user:tj]"); //有权限"user:tj"才可访问
    filter.put("/","anon"); //anon 谁都可以访问 //把filter加载给bean
    bean.setFilterChainDefinitionMap(filter); //当没有登陆时,跳转到此登陆界面
    bean.setLoginUrl("/tologin"); //当没有权限时,跳转到此登陆界面
    bean.setUnauthorizedUrl("/noautho"); return bean;
    }
  • 2、根据用户对象的perm(数据库中代表权限的字段)赋予当前用户权限,下面是UserRealm类中的授权方法:doGetAuthorizationInfo(PrincipalCollection principalCollection)

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //拿到当前登陆的这个对象,根据这个对象的perm属性给其授权
    Subject subject = SecurityUtils.getSubject();
    User currentUser = (User)subject.getPrincipal(); //授权
    info.addStringPermission(currentUser.getPerm()); return info;
    }

三、涉及到的主要代码

ShiroConfig.java

  • 有三病(Bean),分别代表Shiro三核心,Bean1负责给请求设置权限
package com.config;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap;
import java.util.Map; @Configuration
public class ShiroConfig{
//shriofilterbean
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//关联securityManager
bean.setSecurityManager(securityManager); //给请求设置权限
Map<String,String> filter = new LinkedHashMap<>();
filter.put("/user/information","perms[user:gr]");
filter.put("/user/recommend","perms[user:tj]");
filter.put("/","anon"); bean.setFilterChainDefinitionMap(filter); //当没有登陆时,跳转到此登陆界面
bean.setLoginUrl("/tologin"); //当没有权限时,跳转到此登陆界面
bean.setUnauthorizedUrl("/noautho"); return bean;
} //securityManager
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("realm") UserRealm realm){
System.out.println("@securityManager");
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(realm);
return securityManager;
} //realm
@Bean
public UserRealm realm(){
System.out.println("@realm");
return new UserRealm();
} }

UserRealm.java

  • 两方法,一给用户授权,一给登陆认证
package com.config;

import com.pojo.User;
import com.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
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.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired; //自定义的realm
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService; //授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("@授权");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //拿到当前登陆的这个对象,根据这个对象的perm属性给其授权
Subject subject = SecurityUtils.getSubject();
User currentUser = (User)subject.getPrincipal(); //授权
info.addStringPermission(currentUser.getPerm()); return info;
} //认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //先取令牌
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; //根据令牌信息从数据库中取出用户
User user = userService.getUserByEmail(token.getUsername());
if(user==null){
return null; //返回null,则抛出无用户名的异常
} //验证密码,Shiro自动验证,只需要把数据库的密码传过去就好了
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}

RouterController.java

  • 负责接收请求,所有的请求接口都在这
package com.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; @Controller
public class RouterController {
@RequestMapping({"/","/index"})
public String toWelcome(){
return "index";
} @RequestMapping("/user/information")
public String toInformation(){
return "user/information";
} @RequestMapping("/user/recommend")
public String toRecommend(){
return "user/recommend";
} @RequestMapping("/tologin")
public String toLogin(){
return "login";
} @RequestMapping("/login")
public String login(String usr, String pwd, Model model){ //获取当前用户
Subject subject = SecurityUtils.getSubject(); //封装用户的登陆数据,生成令牌
UsernamePasswordToken token = new UsernamePasswordToken(usr,pwd); //用令牌登陆,如果没有异常则登陆成功
try{
subject.login(token);
//无异常则登陆成功
return "index";
}catch(UnknownAccountException e){
model.addAttribute("msg","用户名错误");
return "login";
}catch(IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
} @RequestMapping("/noautho")
@ResponseBody
public String toNoautho(){
return "没有权限访问!";
}
}

Shiro+Mybatis实现登录认证、授权功能的更多相关文章

  1. Django 中自定义用户模型及集成认证授权功能总结

    1. 概述 Django 中的 django.contrib.auth 应用提供了完整的用户及认证授权功能. Django 官方推荐基于内置 User 数据模型创建新的自定义用户模型,方便添加 bir ...

  2. springboot,vue,shiro整合 关于登录认证功能

    首先是session问题 传统session认证 http协议是一种无状态协议,即浏览器发送请求到服务器,服务器是不知道这个请求是哪个用户发来的.为了让服务器知道请求是哪个用户发来的,需要让用户提供用 ...

  3. SpringBoot整合shiro实现用户的认证授权

    * 项目环境搭建 * 配置ShiroConfig,用于shiro的基本配置和注入自定义规则 * 实现自定义的realm,继承AuthorizingRealm * 编写测试controller和页面 基 ...

  4. shiro 实现 网站登录记住我功能 学习记录(四)

    在很多网站都有在登录的时候,比如说记住我 几天之内  只要再此打开这个网站,都不需要再登录的情况: 1.前台JSP增加 单选框:记住我 如 2.在处理登录的 Controller 代码中增加接收这个参 ...

  5. Shiro学习笔记 三(认证授权)

    第一种首先基于角色的权限控制 1.由于不断的创建SecurityFactory工程等步骤重复多次,所以应该将这些步骤封装成一个工具类 还是首先看一下目录结构 主要用到文件 首先贴一下工具类的方法 pa ...

  6. Cassandra的登录认证授权

    cassandra的登录验证机制是独自的,数据是集群共享的 参考:http://blog.csdn.net/y_y_y_k_k_k_k/article/category/5943357 1.初始安装启 ...

  7. 【项目实践】一文带你搞定Session和JWT的登录认证方式

    以项目驱动学习,以实践检验真知 前言 登录认证,估计是所有系统中最常见的功能了,并且也是最基础.最重要的功能.为了做好这一块而诞生了许多安全框架,比如最常见的Shiro.Spring Security ...

  8. 阶段5 3.微服务项目【学成在线】_day18 用户授权_10-前端集成认证授权-需求分析

    4 前端集成认证授权 4.1 需求分析 截至目前认证授权服务端的功能已基本完成,本章实现前端集成认证授权功能. 前端集成认证授权功能需要作如下工作: 1.前端页面校验用户的身份,如果用户没有登录则跳转 ...

  9. Vue结合Django-Rest-Frameword结合实现登录认证(一)

    作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/2436173500265335 微信公众 ...

随机推荐

  1. iview使用之怎样通过render函数在tabs组件中添加标签

    在实际项目开发中我们通常会遇到一些比较'新颖'的需求,而这时iview库里往往没有现成可用的组件示例,所以我们就需要自己动手翻阅IviewAPI进行自定义一些组件,也可以说是将iview库里的多种组件 ...

  2. WebApi参数检查验证FluentValidation的使用方法

    右键打开NuGet程序包管理,进入浏览,搜索 FluentValidation,点击下载 在Model文件夹添加一个Person类进行校验 校验前,using需要引入相应的命名空间方可使用,Abstr ...

  3. 设计可靠的udp

    推荐链接: https://www.cnblogs.com/lixiang-share/p/7152870.html

  4. VirtualBox 原始镜像转换成 vdi 镜像

    VBoxManage convertdd [-static] <filename> <outputfile> 将raw硬盘转换成vdi虚拟硬盘

  5. 修改mysql配置中my.conf中max_allowed_packet变量

    mysql根据配置文件会限制server接受的数据包大小. 有时候大的插入和更新会受max_allowed_packet 参数限制,导致写入或者更新失败. 查看目前配置 show VARIABLES ...

  6. MyBatis学习总结(9)——使用MyBatis Generator自动创建代码

    2019独角兽企业重金招聘Python工程师标准>>> 由于MyBatis属于一种半自动的ORM框架,所以主要的工作就是配置Mapping映射文件,但是由于手写映射文件很容易出错,所 ...

  7. ACM卡常处理办法(虽然我到现在没遇到)

    今天做预流推送,一样的代码.别人500MS(OI选手)而我5S,百思不得其解,然后我知道了还有卡常这一说. 我们今天就来看一看吧: 1.循环展开: 在缓存和寄存器允许的情况下一条语句内大量的展开运算会 ...

  8. HTML(标题/图片/链接/列表标签)

    <!DOCTYPE html> 声明 <!DOCTYPE html> 是 html5 标准网页声明,全称为 Document Type HyperText Mark-up La ...

  9. 似乎是最实用的hashtable知识总结

    哈希表:将对象转换为索引,然后存储在数组中. 定义注意点: 对象:就是面向对象中的对象,可以为任何东西.整数.浮点数.日期.字符串.类. 转换:通过hash函数来完成,hash函数是hash表的核心与 ...

  10. Java——多线程之Lock锁

    Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...