Shiro多Realm验证
在单Realm的基础上,进行如下内容的修改
原有的ShiroRealm.java:
package com.atguigu.shiro.realms; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource; public class ShiroRealm extends AuthenticatingRealm { @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("[ShiroRealm] doGetAuthenticationInfo"); //1. 把AuthenticationToken 转换为 UsernamePasswordToken
UsernamePasswordToken upToken = (UsernamePasswordToken)token; //2. 从UsernamePasswordToken 中来获取username
String username = upToken.getUsername(); //3.调用数据库的方法,从数据库查询username 对应的用户记录
System.out.println("从数据库中获取username:" + username +" 所对应的用户信息"); //4.若用户不存在可以抛出 UnknownAccountException 异常
if ("unknown".equals(username)) {
throw new UnknownAccountException("用户不存在");
} //5.根据用户信息的情况,决定是否抛出其它的 AuthenticationException 异常
if ("monster".equals(username)) {
throw new LockedAccountException("用户被锁定");
} //6.根据用户的情况,来构建 AuthenticationToken 对象并返回,通常使用的实现类为:SimpleAuthenticationInfo
//一下信息是从数据库中获取的
//1).principals:认证的实体信息,可以是username,也可以是数据表对应的实体类对象
Object principal = username;
//2).credentials:密码
Object hashedCredentials = null; //"fc1709d0a95a6be30bc5926fdb7f22f4";
if ("admin".equals(username)) {
hashedCredentials = "038bdaf98f2037b31f1e75b5b4c9b26e";
}else if("user".equals(username)) {
hashedCredentials = "098d2c478e9c11555ce2823231e02ec1";
} //3).realmName:当前realm 对象的name,调用父类的getName()方法即可
String realmName = getName();
//4).盐值
//SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credential,realmName);
//因为用户名唯一,使用用户名作为盐值
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
return info;
} public static void main(String[] args) {
String algorithmName = "MD5";
Object password = "123456";
Object salt = ByteSource.Util.bytes("admin");
int hashIterations = 1024;
Object result = new SimpleHash(algorithmName, password, salt, hashIterations);
System.out.println(result);
} }
添加SecondRealm.java:
package com.atguigu.shiro.realms; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource; public class SecondRealm extends AuthenticatingRealm { @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("[SecondRealm] doGetAuthenticationInfo"); //1. 把AuthenticationToken 转换为 UsernamePasswordToken
UsernamePasswordToken upToken = (UsernamePasswordToken)token; //2. 从UsernamePasswordToken 中来获取username
String username = upToken.getUsername(); //3.调用数据库的方法,从数据库查询username 对应的用户记录
System.out.println("从数据库中获取username:" + username +" 所对应的用户信息"); //4.若用户不存在可以抛出 UnknownAccountException 异常
if ("unknown".equals(username)) {
throw new UnknownAccountException("用户不存在");
} //5.根据用户信息的情况,决定是否抛出其它的 AuthenticationException 异常
if ("monster".equals(username)) {
throw new LockedAccountException("用户被锁定");
} //6.根据用户的情况,来构建 AuthenticationToken 对象并返回,通常使用的实现类为:SimpleAuthenticationInfo
//一下信息是从数据库中获取的
//1).principals:认证的实体信息,可以是username,也可以是数据表对应的实体类对象
Object principal = username;
//2).credentials:密码
Object hashedCredentials = null; //"fc1709d0a95a6be30bc5926fdb7f22f4";
if ("admin".equals(username)) {
hashedCredentials = "ce2f6417c7e1d32c1d81a797ee0b499f87c5de06";
}else if("user".equals(username)) {
hashedCredentials = "073d4c3ae812935f23cb3f2a71943f49e082a718";
} //3).realmName:当前realm 对象的name,调用父类的getName()方法即可
String realmName = getName();
//4).盐值
//SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credential,realmName);
//因为用户名唯一,使用用户名作为盐值
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
return info;
} public static void main(String[] args) {
String algorithmName = "SHA1";
Object password = "123456";
Object salt = ByteSource.Util.bytes("admin");
int hashIterations = 1024;
Object result = new SimpleHash(algorithmName, password, salt, hashIterations);
System.out.println(result);
} }
修改applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- =========================================================
Shiro Core Components - Not Spring Specific
========================================================= -->
<!-- Shiro's main business-tier object for web-enabled applications
(use DefaultSecurityManager instead when there is no web environment)-->
<!--
1.配置SecurityManager!
-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<!-- 单个Realm -->
<!-- <property name="realm" ref="jdbcRealm"/> -->
<!-- 多Realm -->
<property name="authenticator" ref="authenticator"/>
</bean> <!-- Let's use some enterprise caching support for better performance. You can replace this with any enterprise
caching framework implementation that you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc --> <!--
2.配置cacheManager
2.1 需要加入ehcache的jar包及配置文件
-->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- Set a net.sf.ehcache.CacheManager instance here if you already have one. If not, a new one
will be creaed with a default config:
<property name="cacheManager" ref="ehCacheManager"/> -->
<!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
a specific Ehcache configuration to be used, specify that here. If you don't, a default
will be used.: -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean> <!-- 将两个Realm配置到认证器中 -->
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
<property name="realms">
<list>
<ref bean="jdbcRealm"/>
<ref bean="secondRealm"/>
</list>
</property>
</bean>
<!-- Used by the SecurityManager to access security data (users, roles, etc).
Many other realm implementations can be used too (PropertiesRealm,
LdapRealm, etc. --> <!--
3.配置Realm
3.1直接配置实现了com.atguigu.shiro.realms.ShiroRealm接口的bean
-->
<bean id="jdbcRealm" class="com.atguigu.shiro.realms.ShiroRealm">
<!-- 配置MD5加密 -->
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 指定加密方式为MD5 -->
<property name="hashAlgorithmName" value="MD5"></property>
<!-- 指定加密次数 -->
<property name="hashIterations" value="1024"></property>
</bean>
</property>
</bean> <bean id="secondRealm" class="com.atguigu.shiro.realms.SecondRealm">
<!-- 配置MD5加密 -->
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 指定加密方式为MD5 -->
<property name="hashAlgorithmName" value="SHA1"></property>
<!-- 指定加密次数 -->
<property name="hashIterations" value="1024"></property>
</bean>
</property>
</bean> <!-- =========================================================
Shiro Spring-specific integration
========================================================= -->
<!-- Post processor that automatically invokes init() and destroy() methods
for Spring-configured Shiro objects so you don't have to
1) specify an init-method and destroy-method attributes for every bean
definition and
2) even know which Shiro objects require these methods to be
called. -->
<!--
4.配置LifecycleBeanPostProcessor,可以自动地来调用配置在Spring IOC容器中shiro bean的生命周期方法
-->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- Enable Shiro Annotations for Spring-configured beans. Only run after
the lifecycleBeanProcessor has run: --> <!--
5.启用IOC容器中使用shiro的注解,但必须在配置了LifecycleBeanPostProcessor之后才可以使用
-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
web.xml uses the DelegatingFilterProxy to access this bean. This allows us
to wire things with more control as well utilize nice Spring things such as
PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: --> <!--
6.配置ShiroFilter
6.1 id必须和web.xml文件中配置的DelegatingFilterProxy的 <filter-name> 一致
若不一致,则会抛出:NoSuchBeanDefinitionException. 因为 Shiro 会来 IOC 容器中查找和 <filter-name> 名字对应的 filter bean.
6.2
-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.jsp"/>
<property name="successUrl" value="/list.jsp"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/> <!--
配置哪些页面需要受保护
以及访问这些页面需要的权限
1). anon 可以被匿名访问
2). authc 必须认证(即登录)后才可以访问的页面
3). logout 登出
-->
<property name="filterChainDefinitions">
<value>
/login.jsp = anon
/shiro/login = anon
/shiro/logout = logout
# everything else requires authentication:
/** = authc
</value>
</property>
</bean>
</beans>
Shiro多Realm验证的更多相关文章
- shiro双realm验证
假设现在有这样一种需求:存在两张表user和admin,分别记录普通用户和管理员的信息.并且现在要实现普通用户和管理员的分开登录,即需要两个Realm——UserRealm和AdminRealm,分别 ...
- shiro多realm验证之——shiro实现不同身份使用不同Realm进行验证(转)
转自: http://blog.csdn.net/xiangwanpeng/article/details/54802509 (使用特定的realm实现特定的验证) 假设现在有这样一种需求:存在两张表 ...
- Shiro自定义realm实现密码验证及登录、密码加密注册、修改密码的验证
一:先从登录开始,直接看代码 @RequestMapping(value="dologin",method = {RequestMethod.GET, RequestMethod. ...
- Shiro固定身份验证
Shiro基础身份验证 如果要进行shiro的日志信息读取,那么需要使用一个org.apache.shiro.util.Factory接口,在这个接口里面定义有一 取得SecuruityManager ...
- 基于权限安全框架Shiro的登录验证功能实现
目前在企业级项目里做权限安全方面喜欢使用Apache开源的Shiro框架或者Spring框架的子框架Spring Security. Apache Shiro是一个强大且易用的Java安全框架,执行身 ...
- Shiro笔记(四)Shiro的realm认证
认证流程: 1.获取当前Subject.调用SecurityUtils.getSubject(); 2.测试当前用户是否已经被认证,即是否已经登录,调用Subject的isAurhenticated( ...
- Shiro中Realm
6.1 Realm [2.5 Realm]及[3.5 Authorizer]部分都已经详细介绍过Realm了,接下来再来看一下一般真实环境下的Realm如何实现. 1.定义实体及关系 即用户-角色 ...
- shiro登陆权限验证
一>引入shirojar包 <!-- shiro登陆权限控制 --> <dependency> <groupId>org. ...
- shiro自定义Realm
1.1 自定义Realm 上边的程序使用的是shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm. ...
随机推荐
- 191107Django的Cookie和Session
Cookie的使用 from django.shortcuts import render,redirect def login(request): print("1",reque ...
- SpringBoot中application.yml基本配置详情
把原有的application.properties删掉.然后 maven -X clean install,或者通过Maven Project双击clean和install(1)端口服务配置 #端口 ...
- linux 中文乱码解决办法
就是从数据库中取出来时,在存入linux的文件里时,在字符流时制定编码格式.代码如下: FileOutputStream fos=new FileOutputStream(new File(fileP ...
- js对数组分组处理
一.js数组分组 1.js对数据分组类似group by 源码如下: <!DOCTYPE html> <html lang="en"> <head&g ...
- configprase模块,配置文件模块
import configparser # config = configparser.ConfigParser() # config["DEFAULT"] = {'Port':3 ...
- tomcat 日志拆分
一.用cronolog分割tomcat的catalina.out文件 1.编译安装cronologwget http://cronolog.org/download/cronolog-1.6.2.ta ...
- Android地图开发获取sHA1值方法
public static String sHA1(Context context) { try { PackageInfo info = context.getPackageManager().ge ...
- 我们公司的delphi代码(胆不是我写的!),看看,你觉得怎么样
unit unt_LotBill_dyc; interface uses windows, SysUtils, Classes, ComCtrls, Forms, Controls, StrUtils ...
- Hibernate框架 初识 ORM概念
Hibernate概述 Hibernate是一个ORM(对象关系映射)映射框架,它的核心思想就是在底层对JDBC进行了一次封装. 什么是框架 IT语境中的框架,特指为解决一个开放性问题而设计的具有一定 ...
- java:Oracle(视图,索引,序列)
1.索引:索引一共分为4种 -- 在oracle中, -- normal:普通索引 -- unique:唯一索引 -- bitmap:位图索引 -- B 树索引:默认:如果不建立索引的情况下,orac ...