使用Shiro验证和授权

版权声明:博文主要参考网上资料,视频笔记,结合个人见解,仅供学习、交流使用,如有侵权,请联系博主删除。 https://blog.csdn.net/qq_40293674/article/details/87283149

Shiro执行流程

Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进 程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。 
Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。 

SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。 

Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。 
从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。 
Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。

使用shiro验证和授权

  1. 准备工作:导入shiro jar包,添加applicationContext_shiro.xml,web.xml添加的过滤器链.txt

使用shiro进行认证

1、创建令牌

2、得到主题subject

3、执行认证

4、自定义realm

5、配置自定义realm

6、修改配置资源访问规则

public void checkUser(){

/**

 * 使用shiro认证方式步骤

 * 1、创建令牌

 * 2、得到subject

 * 3、执行认证

 * 4、自定义realm

 * 5、配置自定义realm

 * 6、修改配置资源访问规则

 */

/**

 * 加密明文密码

 */

Md5Hash md5Hash = new Md5Hash(pwd, username, 2);

System.out.println("md5Hash===="+md5Hash);

//创建认证

UsernamePasswordToken token = new UsernamePasswordToken(username,md5Hash.toString());

//获得subject

Subject subject = SecurityUtils.getSubject();

try {

//执行认证

subject.login(token);

//将登陆的用户保存到session域中

//获得登陆用户

Emp user = (Emp) subject.getPrincipal();//执行此行代码有安全管理器调用自定义realm

ActionContext.getContext().getSession().put("user", user);

//向客户端写登陆成功信息

write(ajaxReturn(true, "登陆成功"));

} catch (Exception e) {

e.printStackTrace();

write(ajaxReturn(false, "用户名或密码不正确"));

}

//传统方式登录校验

/*Emp emp = empBiz.findByUsernameAndPwd(username, pwd);

if(emp==null){

write(ajaxReturn(false, "用户名和密码错误!"));

}else

{

//将emp对象放入session

ActionContext.getContext().getSession().put("user", emp);

write(ajaxReturn(true, "登陆成功"));

}*/

}

自定义realm

package cn.itcast.erp.realm;

import java.util.List;

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.authc.UsernamePasswordToken;

import org.apache.shiro.authz.AuthorizationInfo;

import org.apache.shiro.authz.SimpleAuthorizationInfo;

import org.apache.shiro.crypto.hash.Md5Hash;

import org.apache.shiro.realm.AuthorizingRealm;

import org.apache.shiro.subject.PrincipalCollection;

import cn.itcast.erp.biz.IEmpBiz;

import cn.itcast.erp.biz.IMenuBiz;

import cn.itcast.erp.entity.Emp;

import cn.itcast.erp.entity.Menu;

public class ErpRealm extends AuthorizingRealm {

//注入empBiz对象

IEmpBiz empBiz;

IMenuBiz menuBiz;

public void setMenuBiz(IMenuBiz menuBiz) {

this.menuBiz = menuBiz;

}

public void setEmpBiz(IEmpBiz empBiz) {

this.empBiz = empBiz;

}

/**

 * 授权。控制用户可以访问到的资源

 * 1、通过主角得到当前登录的用户对象

 * 2、实例化授权信息

 * 3、获取访问资源集合

 * 4、绑定授权资源信息

 * 5、编写规则

 */

protected AuthorizationInfo doGetAuthorizationInfo(

PrincipalCollection principals) {

System.out.println("runing..................");

//通过主角得到当前登录的用户对象

Emp emp = (Emp) principals.getPrimaryPrincipal();

//实例化授权信息

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//获取访问资源集合

List<Menu> menuList = menuBiz.getMenusByEmpuuid(emp.getUuid());

//绑定授权资源信息

for(Menu list:menuList){

info.addStringPermission(list.getMenuname());

}

return info;

}

/**

 * 认证方法

 * 1、获得令牌

 * 2、调用业务逻辑进行登录判段

 * 3、根据结果返回值

 */

@Override

protected AuthenticationInfo doGetAuthenticationInfo(

AuthenticationToken token) throws AuthenticationException {

//获得令牌

UsernamePasswordToken userToken=(UsernamePasswordToken)token;

//获取用户名和和密码

String username = userToken.getUsername();//获取的用户名

String password = new String(userToken.getPassword()); //获取密码

//调用业务逻辑进行登录判段

Emp emp = empBiz.findByUsernameAndPwd(username,password);

//根据结果返回值

if(emp==null){

return null;

}

//返回认证实例

/**

 * emp,登录用户

 * emp.getPwd(),密码

 * getName(),realm类名

 */

SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(emp, emp.getPwd(), getName());

return simpleAuthenticationInfo;

}

}

配置

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" depends-on="myFilter">

<!-- 安全管理器 -->

<property name="securityManager" ref="securityManager" />

<!-- 认证相关的配置,当用户没有登录,自动跳转到登录页面 -->

<property name="loginUrl" value="/login.html" />

<!-- 授权相关的配置:当用户没有权限访问时自动条状到该页面 -->

<property name="unauthorizedUrl" value="/error.html" />

<!-- 配置自定义过滤器 -->

<property name="filters">

<map>

<entry key="perms" value-ref="myFilter"></entry>

</map>

</property>

<!-- 过滤链的定义:配置资源访问规则 -->

<property name="filterChainDefinitions">

<value>

/error.html = anon

/login_*.action = anon

<!-- 安全管理器核心组件 -->

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

<!-- 注入自定义realm -->

<property name="realm" ref="erpRealm"></property>

</bean>

<!-- 自定义realm .注入empBiz -->

<bean id="erpRealm" class="cn.itcast.erp.realm.ErpRealm">

<property name="empBiz" ref="empBiz"></property>

<property name="menuBiz" ref="menuBiz"></property>

</bean>

<!-- 自定义授权过滤器 -->

<bean id="myFilter" class="cn.itcast.erp.filter.MyFilter"></bean>

</beans>

授权操作步骤:

  1. 通过主角得到当前登录用户对象
  2. 实例化授权信息
  3. 获取访问资源集合
  4. 绑定授权资源信息
  5. 编写规则(必须有)

/**

 * 授权。控制用户可以访问到的资源

 * 1、通过主角得到当前登录的用户对象

 * 2、实例化授权信息

 * 3、获取访问资源集合

 * 4、绑定授权资源信息

 * 5、编写规则

 */

protected AuthorizationInfo doGetAuthorizationInfo(

PrincipalCollection principals) {

System.out.println("runing..................");

//通过主角得到当前登录的用户对象

Emp emp = (Emp) principals.getPrimaryPrincipal();

//实例化授权信息

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//获取访问资源集合

List<Menu> menuList = menuBiz.getMenusByEmpuuid(emp.getUuid());

//绑定授权资源信息

for(Menu list:menuList){

info.addStringPermission(list.getMenuname());

}

return info;

}

授权操作:

  1. url方式
  2. 自定义过滤器

1、编写自定义过滤器,继承AuthorizationFilter

2、在shiro配置文件中配置自定义过滤器,将自定义过滤器交给spring容器管理

3、在配置文件中将自定义过滤器资源加入到shiroFilter Bean配置中,必须加入depends-on="myFilter"属性

4、编码方式编写规则

4、细颗粒方式也就是编码方式控制

使用shiro加密

直接调用方法:

Md5Hash md5Hash = new Md5Hash(pwd, username, 2);

System.out.println("md5Hash===="+md5Hash);

使用shiro技术可能会遇到的问题

  1. 没有将相关资源注入spring容器
  2. 使用授权没有生效,没有配置规则或则配置规则无效

 

猜你喜欢

转载自blog.csdn.net/qq_40293674/article/details/87283149