zoukankan      html  css  js  c++  java
  • Shiro多Realm验证

    在单Realm的基础上,进行如下内容的修改

    原有的ShiroRealm.java:

     1 package com.atguigu.shiro.realms;
     2 
     3 import org.apache.shiro.authc.AuthenticationException;
     4 import org.apache.shiro.authc.AuthenticationInfo;
     5 import org.apache.shiro.authc.AuthenticationToken;
     6 import org.apache.shiro.authc.LockedAccountException;
     7 import org.apache.shiro.authc.SimpleAuthenticationInfo;
     8 import org.apache.shiro.authc.UnknownAccountException;
     9 import org.apache.shiro.authc.UsernamePasswordToken;
    10 import org.apache.shiro.crypto.hash.SimpleHash;
    11 import org.apache.shiro.realm.AuthenticatingRealm;
    12 import org.apache.shiro.util.ByteSource;
    13 
    14 public class ShiroRealm extends AuthenticatingRealm {
    15 
    16     @Override
    17     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    18 
    19         System.out.println("[ShiroRealm] doGetAuthenticationInfo");
    20         
    21         //1. 把AuthenticationToken 转换为 UsernamePasswordToken
    22         UsernamePasswordToken upToken = (UsernamePasswordToken)token;
    23         
    24         //2. 从UsernamePasswordToken 中来获取username
    25         String username = upToken.getUsername();
    26         
    27         //3.调用数据库的方法,从数据库查询username 对应的用户记录
    28         System.out.println("从数据库中获取username:" + username +" 所对应的用户信息");
    29         
    30         //4.若用户不存在可以抛出 UnknownAccountException 异常
    31         if ("unknown".equals(username)) {
    32             throw new UnknownAccountException("用户不存在");
    33         }
    34         
    35         //5.根据用户信息的情况,决定是否抛出其它的 AuthenticationException 异常
    36         if ("monster".equals(username)) {
    37             throw new LockedAccountException("用户被锁定");
    38         }
    39         
    40         //6.根据用户的情况,来构建 AuthenticationToken 对象并返回,通常使用的实现类为:SimpleAuthenticationInfo 
    41         //一下信息是从数据库中获取的
    42         //1).principals:认证的实体信息,可以是username,也可以是数据表对应的实体类对象
    43         Object principal = username;
    44         //2).credentials:密码
    45         Object hashedCredentials = null; //"fc1709d0a95a6be30bc5926fdb7f22f4";
    46         if ("admin".equals(username)) {
    47             hashedCredentials = "038bdaf98f2037b31f1e75b5b4c9b26e";
    48         }else if("user".equals(username)) {
    49             hashedCredentials = "098d2c478e9c11555ce2823231e02ec1";
    50         }
    51         
    52         
    53         //3).realmName:当前realm 对象的name,调用父类的getName()方法即可
    54         String realmName = getName();
    55         //4).盐值
    56         //SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credential,realmName);
    57         //因为用户名唯一,使用用户名作为盐值
    58         ByteSource credentialsSalt = ByteSource.Util.bytes(username);
    59         SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
    60         return info;
    61     }
    62     
    63     public static void main(String[] args) {
    64         String algorithmName = "MD5";
    65         Object password = "123456";
    66         Object salt = ByteSource.Util.bytes("admin");
    67         int hashIterations = 1024;
    68         Object result = new SimpleHash(algorithmName, password, salt, hashIterations);
    69         System.out.println(result);
    70     }
    71 
    72 }

    添加SecondRealm.java:

     1 package com.atguigu.shiro.realms;
     2 
     3 import org.apache.shiro.authc.AuthenticationException;
     4 import org.apache.shiro.authc.AuthenticationInfo;
     5 import org.apache.shiro.authc.AuthenticationToken;
     6 import org.apache.shiro.authc.LockedAccountException;
     7 import org.apache.shiro.authc.SimpleAuthenticationInfo;
     8 import org.apache.shiro.authc.UnknownAccountException;
     9 import org.apache.shiro.authc.UsernamePasswordToken;
    10 import org.apache.shiro.crypto.hash.SimpleHash;
    11 import org.apache.shiro.realm.AuthenticatingRealm;
    12 import org.apache.shiro.util.ByteSource;
    13 
    14 public class SecondRealm extends AuthenticatingRealm {
    15 
    16     @Override
    17     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    18 
    19         System.out.println("[SecondRealm] doGetAuthenticationInfo");
    20         
    21         //1. 把AuthenticationToken 转换为 UsernamePasswordToken
    22         UsernamePasswordToken upToken = (UsernamePasswordToken)token;
    23         
    24         //2. 从UsernamePasswordToken 中来获取username
    25         String username = upToken.getUsername();
    26         
    27         //3.调用数据库的方法,从数据库查询username 对应的用户记录
    28         System.out.println("从数据库中获取username:" + username +" 所对应的用户信息");
    29         
    30         //4.若用户不存在可以抛出 UnknownAccountException 异常
    31         if ("unknown".equals(username)) {
    32             throw new UnknownAccountException("用户不存在");
    33         }
    34         
    35         //5.根据用户信息的情况,决定是否抛出其它的 AuthenticationException 异常
    36         if ("monster".equals(username)) {
    37             throw new LockedAccountException("用户被锁定");
    38         }
    39         
    40         //6.根据用户的情况,来构建 AuthenticationToken 对象并返回,通常使用的实现类为:SimpleAuthenticationInfo 
    41         //一下信息是从数据库中获取的
    42         //1).principals:认证的实体信息,可以是username,也可以是数据表对应的实体类对象
    43         Object principal = username;
    44         //2).credentials:密码
    45         Object hashedCredentials = null; //"fc1709d0a95a6be30bc5926fdb7f22f4";
    46         if ("admin".equals(username)) {
    47             hashedCredentials = "ce2f6417c7e1d32c1d81a797ee0b499f87c5de06";
    48         }else if("user".equals(username)) {
    49             hashedCredentials = "073d4c3ae812935f23cb3f2a71943f49e082a718";
    50         }
    51         
    52         
    53         //3).realmName:当前realm 对象的name,调用父类的getName()方法即可
    54         String realmName = getName();
    55         //4).盐值
    56         //SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credential,realmName);
    57         //因为用户名唯一,使用用户名作为盐值
    58         ByteSource credentialsSalt = ByteSource.Util.bytes(username);
    59         SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
    60         return info;
    61     }
    62     
    63     public static void main(String[] args) {
    64         String algorithmName = "SHA1";
    65         Object password = "123456";
    66         Object salt = ByteSource.Util.bytes("admin");
    67         int hashIterations = 1024;
    68         Object result = new SimpleHash(algorithmName, password, salt, hashIterations);
    69         System.out.println(result);
    70     }
    71 
    72 }

    修改applicationContext.xml:

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <beans xmlns="http://www.springframework.org/schema/beans"
      3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      5 
      6     <!-- =========================================================
      7          Shiro Core Components - Not Spring Specific
      8          ========================================================= -->
      9     <!-- Shiro's main business-tier object for web-enabled applications
     10          (use DefaultSecurityManager instead when there is no web environment)-->
     11     <!-- 
     12         1.配置SecurityManager!
     13      -->
     14     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
     15         <property name="cacheManager" ref="cacheManager"/>
     16         <!-- 单个Realm -->
     17         <!-- <property name="realm" ref="jdbcRealm"/> -->
     18         <!-- 多Realm -->
     19         <property name="authenticator" ref="authenticator"/>
     20     </bean>
     21 
     22     <!-- Let's use some enterprise caching support for better performance.  You can replace this with any enterprise
     23          caching framework implementation that you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc -->
     24     
     25     <!-- 
     26     2.配置cacheManager
     27     2.1 需要加入ehcache的jar包及配置文件    
     28      -->
     29     <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
     30         <!-- Set a net.sf.ehcache.CacheManager instance here if you already have one.  If not, a new one
     31              will be creaed with a default config:
     32              <property name="cacheManager" ref="ehCacheManager"/> -->
     33         <!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
     34              a specific Ehcache configuration to be used, specify that here.  If you don't, a default
     35              will be used.: -->
     36         <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
     37     </bean>
     38 
     39     <!-- 将两个Realm配置到认证器中 -->
     40     <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
     41         <property name="realms">
     42             <list>
     43                 <ref bean="jdbcRealm"/>
     44                 <ref bean="secondRealm"/>
     45             </list>
     46         </property>
     47     </bean>
     48     <!-- Used by the SecurityManager to access security data (users, roles, etc).
     49          Many other realm implementations can be used too (PropertiesRealm,
     50          LdapRealm, etc. -->
     51     
     52     <!-- 
     53     3.配置Realm
     54     3.1直接配置实现了com.atguigu.shiro.realms.ShiroRealm接口的bean
     55      -->
     56     <bean id="jdbcRealm" class="com.atguigu.shiro.realms.ShiroRealm">
     57         <!-- 配置MD5加密 -->
     58         <property name="credentialsMatcher">
     59             <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
     60                 <!-- 指定加密方式为MD5 -->
     61                 <property name="hashAlgorithmName" value="MD5"></property>
     62                 <!-- 指定加密次数 -->
     63                 <property name="hashIterations" value="1024"></property>
     64             </bean>
     65         </property>
     66     </bean>
     67     
     68     <bean id="secondRealm" class="com.atguigu.shiro.realms.SecondRealm">
     69         <!-- 配置MD5加密 -->
     70         <property name="credentialsMatcher">
     71             <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
     72                 <!-- 指定加密方式为MD5 -->
     73                 <property name="hashAlgorithmName" value="SHA1"></property>
     74                 <!-- 指定加密次数 -->
     75                 <property name="hashIterations" value="1024"></property>
     76             </bean>
     77         </property>
     78     </bean>
     79 
     80     <!-- =========================================================
     81          Shiro Spring-specific integration
     82          ========================================================= -->
     83     <!-- Post processor that automatically invokes init() and destroy() methods
     84          for Spring-configured Shiro objects so you don't have to
     85          1) specify an init-method and destroy-method attributes for every bean
     86             definition and
     87          2) even know which Shiro objects require these methods to be
     88             called. -->
     89     <!-- 
     90     4.配置LifecycleBeanPostProcessor,可以自动地来调用配置在Spring IOC容器中shiro bean的生命周期方法
     91      -->
     92     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
     93 
     94     <!-- Enable Shiro Annotations for Spring-configured beans.  Only run after
     95          the lifecycleBeanProcessor has run: -->
     96     
     97     <!-- 
     98     5.启用IOC容器中使用shiro的注解,但必须在配置了LifecycleBeanPostProcessor之后才可以使用
     99      -->
    100     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
    101           depends-on="lifecycleBeanPostProcessor"/>
    102     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    103         <property name="securityManager" ref="securityManager"/>
    104     </bean>
    105 
    106     <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
    107          web.xml uses the DelegatingFilterProxy to access this bean.  This allows us
    108          to wire things with more control as well utilize nice Spring things such as
    109          PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: -->
    110     
    111     <!-- 
    112     6.配置ShiroFilter
    113     6.1 id必须和web.xml文件中配置的DelegatingFilterProxy的 <filter-name> 一致
    114         若不一致,则会抛出:NoSuchBeanDefinitionException. 因为 Shiro 会来 IOC 容器中查找和 <filter-name> 名字对应的 filter bean.
    115     6.2
    116      -->
    117     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    118         <property name="securityManager" ref="securityManager"/>
    119         <property name="loginUrl" value="/login.jsp"/>
    120         <property name="successUrl" value="/list.jsp"/>
    121         <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
    122         
    123         <!-- 
    124             配置哪些页面需要受保护
    125             以及访问这些页面需要的权限
    126             1). anon 可以被匿名访问
    127             2). authc 必须认证(即登录)后才可以访问的页面
    128             3). logout 登出
    129          -->
    130         <property name="filterChainDefinitions">
    131             <value>
    132                 /login.jsp = anon
    133                 /shiro/login = anon
    134                 /shiro/logout = logout
    135                 # everything else requires authentication:
    136                 /** = authc
    137             </value>
    138         </property>
    139     </bean>
    140 </beans>
  • 相关阅读:
    系统集成项目管理工程师计算题(成本管理计算)
    系统集成项目管理工程师计算题(进度管理计算)
    系统集成项目管理工程师计算题(期望值)
    系统集成项目管理工程师计算题(三点估算)
    系统集成项目管理工程师计算题(沟通渠道)
    Asp.net core web Api 应用Jwt 验证
    Linux vmstat命令
    关于Java集合的小抄
    @Resource和@Autowire
    Servlet是线程安全的吗?
  • 原文地址:https://www.cnblogs.com/116970u/p/11172047.html
Copyright © 2011-2022 走看看