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. linq深入

    一.匿名类:[ C# 3.0/.NET 3.x 新增特性 ] 1.1 不好意思,我匿了 在开发中,我们有时会像下面的代码一样声明一个匿名类:可以看出,在匿名类的语法中并没有为其命名,而是直接的一个ne ...

  2. 2层感知机(神经网络)实现非线性回归(非线性拟合)【pytorch】

    import torch import numpy import random from torch.autograd import Variable import torch.nn.function ...

  3. CSS选择器与CSS的继承,层叠和特殊性

    什么是选择器?选择器{样式;},在{}之前的部分就是"选择器","选择器"指明了{}中的"样式"的作用对象,也就是"样式" ...

  4. 14个快捷键让你的idea飞起来(新手向 + 演示)

    本期盘点一下博主在工作中,常用的13个idea快捷键,这些快捷键基本涵盖了大部分的开发场景,希望可以萌新们的idea使用效率,系统为mac系统 上一步 / 下一步撤销 / 反撤销进入一个类生成方法变量 ...

  5. swoole--服务平滑重启

    参考来源:https://wiki.swoole.com/wiki/page/p-server/reload.html shell代码: echo "loading..." pid ...

  6. Windows VHD Create, Attach, 获得Disk序号

    // create_vhd.cpp : Defines the entry point for the console application. // #include "stdafx.h& ...

  7. nginx 配置多个 https 域名访问

    需要此操作的原因 在服务器上部署了 halo blog 以后,这次需要部署另外一个项目,但是又不想使用 ip + port,因此选择使用 nginx 配置多个域名访问. nginx 配置 server ...

  8. 【JAVA基础】09 Eclipse

    1. Java开发工具 操作系统自带的记事本软件 高级记事本软件 集成开发环境 IDE (Integrated Development Environment) Eclipse和MyEclipse的区 ...

  9. Express 文档(常见问题)

    常见问题 我该如何构建我的应用程序? 这个问题没有明确的答案,答案取决于你的应用程序规模和所涉及的团队,为了尽可能灵活,Express在结构方面没有做出任何假设. 在你喜欢的任何目录结构中,路由和其他 ...

  10. Java反射详细介绍

    反射 目录介绍 1.反射概述 1.1 反射概述 1.2 获取class文件对象的三种方式 1.3 反射常用的方法介绍 1.4 反射的定义 1.5 反射的组成 1.6 反射的作用有哪些 2.反射的相关使 ...