zoukankan      html  css  js  c++  java
  • 学习shiro第三天

    今天比较晚,所以只看了shiro的认证策略Authentication Strategy,下面讲讲shiro的三种认证策略。

    1.AtLeastOneSuccessfulStrategy:这个是shiro默认的认证策略,它表示如果存在多个realm来执行认证,只要其中有一个成功,那么认证就成功(这里注意所有的realm都会进行验证,不管是失败还是成功);

    2.AllSuccessfulStrategy:这个策略表示必须所有的realm认证成功才算最终认证成功,哪怕只有一个不成功,那么结果都为认证不成功。(这里也是会将所有的realm都进行验证);

    3.FirstSuccessfulStrategy:它表示只要有一个realm中认证成功了,那么剩下的其它realm都不必进行验证了,直接返回认证成功。注意这里只要遇到第一个成功认证的realm,其他剩下的realm都不会被调用。

    说了三种认证策略的概念,那么我们怎么进行配置认证策略呢?这个问题就要追溯到shiro中进行认证操作的认证器子类modularRealmAuthenticator,它里面有一个属性authenticationStrategy,并且
    modularRealmAuthenticator在它的构造函数中将这个属性默认设置成new AtLeastOneSuccessfulStrategy():

     private AuthenticationStrategy authenticationStrategy;
    
        /*--------------------------------------------
        |         C O N S T R U C T O R S           |
        ============================================*/
    
        /**
         * Default no-argument constructor which
         * {@link #setAuthenticationStrategy(AuthenticationStrategy) enables}  an
         * {@link org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy} by default.
         */
        public ModularRealmAuthenticator() {
            this.authenticationStrategy = new AtLeastOneSuccessfulStrategy();
        }

    所有我们要配置认证策略,只需要配置modularRealmAuthenticator类中的authenticationStrategy属性。下面是配置认证策略的过程:

    [main]
    dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
    dataSource.driverClass=com.mysql.jdbc.Driver
    dataSource.jdbcUrl=jdbc:mysql://localhost:3306/test
    dataSource.user=root
    dataSource.password=root
    myRealm=org.apache.shiro.realm.jdbc.JdbcRealm
    myRealm.dataSource=$dataSource
    
    dataSource1=com.mchange.v2.c3p0.ComboPooledDataSource
    dataSource1.driverClass=com.mysql.jdbc.Driver
    dataSource1.jdbcUrl=jdbc:mysql://localhost:3306/test1
    dataSource1.user=root
    dataSource1.password=root
    myRealm1=org.apache.shiro.realm.jdbc.JdbcRealm
    myRealm1.dataSource=$dataSource1
    #配置认证策略
    authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
    authenticationStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategy
    authenticator.authenticationStrategy=$authenticationStrategy
    securityManager.authenticator=$authenticator
    securityManager.realms=$myRealm,$myRealm1

    在配置认证策略中,我将认证策略配成了FirstSuccessFulStrategy,然后将这个配置了新的认证策略的认证器赋予了SecurityManager中的authenticator属性从而完成了认证策略的配置。为了测试这几个策略的区别,我在shiro.ini文件中又创建了一个realm,并注入了一个新的数据源:

    两个数据库中都有users的表,但是数据并不相同。下面开始认证编码,还是那一套流程:

    package test_JdbcRealm;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.Factory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class TestAuthencationStrategy {
    
        private static final Logger logger = LoggerFactory.getLogger(TestAuthencationStrategy.class);
        
        public static void main(String[] args) {
            //1.创建securityManager工厂
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            //2.获取securityManager实例
            SecurityManager securityManager = factory.getInstance();
            //3.将SecurityManager实例设置到SecurityUtils工具类中
            SecurityUtils.setSecurityManager(securityManager);
            //4。创建Subject实例
            Subject subject = SecurityUtils.getSubject();
            //5.获取token,模拟用户登陆
            UsernamePasswordToken token = new UsernamePasswordToken("wangwu", "456789");
            try {
                //6.认证token
                subject.login(token);
                if(subject.isAuthenticated()) {
                    logger.info("登陆成功");
                }
            } catch (AuthenticationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                logger.error("用户名或密码错误,登陆失败");
            }
        }
    }

     运行控制台输出如下:

    2019-07-26 23:54:32,756 INFO [com.mchange.v2.log.MLog] - MLog clients using slf4j logging. 
    2019-07-26 23:54:33,216 INFO [com.mchange.v2.c3p0.C3P0Registry] - Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10] 
    2019-07-26 23:54:33,344 INFO [org.apache.shiro.config.IniSecurityManagerFactory] - Realms have been explicitly set on the SecurityManager instance - auto-setting of realms will not occur. 
    2019-07-26 23:54:33,373 INFO [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 2zm2h7a4d1dnn281ezvn|7e0ea639, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2zm2h7a4d1dnn281ezvn|7e0ea639, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/test, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ] 
    2019-07-26 23:54:33,677 INFO [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 2zm2h7a4d1dnn281ezvn|6e1567f1, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2zm2h7a4d1dnn281ezvn|6e1567f1, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/test1, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ] 
    2019-07-26 23:54:33,696 INFO [org.apache.shiro.session.mgt.AbstractValidatingSessionManager] - Enabling session validation scheduler... 
    2019-07-26 23:54:33,704 INFO [test_JdbcRealm.TestAuthencationStrategy] - 登陆成功 

    可以看到虽然test数据库中没有wangwu这个用户,但是test1数据库中有,所以myRealm1的认证过程是成功了的,而myRealm的认证过程毋庸置疑是失败了的,但是我们这里配的认证策略是FirstSuccessfulStrategy,所以只要有一个成功,就认证成功。

    我们把认证策略改成AllSuccessfulStrategy再来测试一下上面的认证流程,发现控制台输出了如下内容:

    2019-07-26 23:59:26,933 INFO [com.mchange.v2.log.MLog] - MLog clients using slf4j logging. 
    2019-07-26 23:59:27,323 INFO [com.mchange.v2.c3p0.C3P0Registry] - Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10] 
    2019-07-26 23:59:27,447 INFO [org.apache.shiro.config.IniSecurityManagerFactory] - Realms have been explicitly set on the SecurityManager instance - auto-setting of realms will not occur. 
    2019-07-26 23:59:27,476 INFO [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 2zm2h7a4d1jymk14v9ac3|7e0ea639, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2zm2h7a4d1jymk14v9ac3|7e0ea639, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/test, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ] 
    org.apache.shiro.authc.UnknownAccountException: No account found for user [wangwu]
        at org.apache.shiro.realm.jdbc.JdbcRealm.doGetAuthenticationInfo(JdbcRealm.java:244)
    2019-07-26 23:59:27,761 ERROR [test_JdbcRealm.TestAuthencationStrategy] - 用户名或密码错误,登陆失败 
        at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:571)
        at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doMultiRealmAuthentication(ModularRealmAuthenticator.java:219)
        at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:269)
        at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
        at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
        at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275)
        at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
        at test_JdbcRealm.TestAuthencationStrategy.main(TestAuthencationStrategy.java:30)

    报了用户找不到的异常,因为在test数据库中我们并没有wangwu这个用户,所以myRealm认证是失败的,而我们配置了AllSuccessfulStrategy这个策略,只要有一个认证失败,那么最终就认证失败,因此这里输出了认证失败的提示语。

    以上是我今天所看的shiro认证策略的内容和应用,如果有什么纠正和补充的请在评论区留言,谢谢!

  • 相关阅读:
    【树形DP】ZJOI2008 骑士
    【博弈论】CF 1215D Ticket Game
    【状态压缩DP】HDU 4352 XHXJ'S LIS
    【纯水题】CF 833A The Meaningless Game
    【不知道怎么分类】NOIP2016 蚯蚓
    【状态压缩DP】SCOI2009 围豆豆
    操作系统总结
    概率问题总结
    C++虚函数原理
    一些baidu面经
  • 原文地址:https://www.cnblogs.com/wujianwu/p/11253535.html
Copyright © 2011-2022 走看看