Shiro+Mybatis实现登录认证、授权功能
Shiro+Mybatis实现登录认证、授权功能
一、实现登录认证功能
1、流程:
- 跟据用户提交表单的账号,经Mybatis框架在数据库中查出User对象:
- 如果User为空,则会抛出异常:UnknownAccountException,没有此账户名。
- 如果不为空,则比对表单中的密码和User对象的密码是否相同(shiro框架自动完成,有加密),密码不相同则会抛出异常:IncorrectCredentialsException,密码错误;密码相同,则登陆成功。
- 跟据用户提交表单的账号,经Mybatis框架在数据库中查出User对象:
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实现登录认证、授权功能的更多相关文章
- Django 中自定义用户模型及集成认证授权功能总结
1. 概述 Django 中的 django.contrib.auth 应用提供了完整的用户及认证授权功能. Django 官方推荐基于内置 User 数据模型创建新的自定义用户模型,方便添加 bir ...
- springboot,vue,shiro整合 关于登录认证功能
首先是session问题 传统session认证 http协议是一种无状态协议,即浏览器发送请求到服务器,服务器是不知道这个请求是哪个用户发来的.为了让服务器知道请求是哪个用户发来的,需要让用户提供用 ...
- SpringBoot整合shiro实现用户的认证授权
* 项目环境搭建 * 配置ShiroConfig,用于shiro的基本配置和注入自定义规则 * 实现自定义的realm,继承AuthorizingRealm * 编写测试controller和页面 基 ...
- shiro 实现 网站登录记住我功能 学习记录(四)
在很多网站都有在登录的时候,比如说记住我 几天之内 只要再此打开这个网站,都不需要再登录的情况: 1.前台JSP增加 单选框:记住我 如 2.在处理登录的 Controller 代码中增加接收这个参 ...
- Shiro学习笔记 三(认证授权)
第一种首先基于角色的权限控制 1.由于不断的创建SecurityFactory工程等步骤重复多次,所以应该将这些步骤封装成一个工具类 还是首先看一下目录结构 主要用到文件 首先贴一下工具类的方法 pa ...
- Cassandra的登录认证授权
cassandra的登录验证机制是独自的,数据是集群共享的 参考:http://blog.csdn.net/y_y_y_k_k_k_k/article/category/5943357 1.初始安装启 ...
- 【项目实践】一文带你搞定Session和JWT的登录认证方式
以项目驱动学习,以实践检验真知 前言 登录认证,估计是所有系统中最常见的功能了,并且也是最基础.最重要的功能.为了做好这一块而诞生了许多安全框架,比如最常见的Shiro.Spring Security ...
- 阶段5 3.微服务项目【学成在线】_day18 用户授权_10-前端集成认证授权-需求分析
4 前端集成认证授权 4.1 需求分析 截至目前认证授权服务端的功能已基本完成,本章实现前端集成认证授权功能. 前端集成认证授权功能需要作如下工作: 1.前端页面校验用户的身份,如果用户没有登录则跳转 ...
- Vue结合Django-Rest-Frameword结合实现登录认证(一)
作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/2436173500265335 微信公众 ...
随机推荐
- HTTP Request和Response
一.Servlet 1:实现Servlet接口 servlet生命周期: init方法:tomcat启动时 调用此方法 service方法:访问servlet时默认执行此方法 destroy方法:to ...
- C# WCF的通信模式
wcf 通信模式一般分为三种; 1,请求/响应模式 2,单工模式 3,双工模式 一,请求/响应模式 请求/响应通信是指客户端向服务端发送消息后,服务端会向客户端发送响应.这也意味着在接收到服务的响应以 ...
- kubernetes的cni0和flannel.1的关系?
当容器运行之后,节点之间多了个虚拟接口cni0,它是由flanneld创建的一个虚拟网桥叫cni0,供pod本地通信使用.flanneld为每个pod创建一对veth虚拟设备,一端放在容器接口上,一端 ...
- 不使用tomcat,仅适用javaSE手写服务器--模拟登陆
1.搭建框架 我们只是简单模拟,框架简单分三个模块 a,服务器端server包 b,servlet,根据不同的请求url,利用反射生产对应的servlet c,IO工具包,用来关闭IO流 d,编写we ...
- Windows 自动登录
https://serverfault.com/questions/840557/auto-login-a-user-at-boot-on-windows-server-2016 Use Sysint ...
- Fedora 21下lingo14配置
Install lingo14 during Fedora 21 The first step:Download lingo14Download address:http://www.lindo.co ...
- Spring Boot JPA 中transaction的使用
文章目录 @Transactional的实现 @Transactional的使用 Transaction的传播级别 REQUIRED SUPPORTS MANDATORY NEVER NOT_SUPP ...
- MySQL数据库入门详细笔记
ps: 中括号[]里的内容都是可以省略的,按需要添加 数据库操作 创建数据库 语法:create database [if not exists] 数据名 charset=gbk; create da ...
- SpringCloud之整合Feign
假设提供者有如下服务接口方法 @RestController @RequestMapping("/person") public class PersonController { ...
- Echarts设置点击事件
简单明了. echarts初始化完成之后,给实例对象通过on绑定事件. 这里的事件包括: 'click','dblclick','mousedown','mouseup','mouseover','m ...