A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始



shiro认证过程
1.应用程序构建了一个终端用户认证信息AuthenticationToken实例后,调用Subject.login方法。
2.Subject的实例通常是DelegatingSubject类(或子类)的实例对象,在认证开始时,会委托应用程序设置的SecurityManager实例调用securityManager.login(token)方法。
3.SecurityManager接受到token(令牌)信息后会委托内置的Authenticator的实例(通常是ModularRealmAuthenticator类的实例)调用authenticator.authenticate(token)。ModularRealmAuthenticator在认证过程中会对设置的一个或多个Realm实例进行适配,它实际上为shiro提供了一个可插拔的认证机制。
4.如果在应用程序中配置类多个Realm,ModularRealmAuthenticator会根据配置的AuthenticationStrategy(认证策略)来进行多Realm的认证过程。在Realm被调用后,AuthenticationStrategy将对每一个Realm的结果做出响应。注意:如果应用程序中仅配置了一个Realm,Realm将被直接调用而无需再配置认证策略。
5.判断每一个Realm是否支持提交的token,如果支持,Realm将调用getAuthenticationInfo(token);getAuthenticationInfo方法就是实际认证处理,我们通过覆盖Realm的doGetAuthenticationInfo方法来编写我们自定义的认证处理。

shiro入门程序(用户登录和退出)
创建Java工程

log4j.properties日志配置文件
  • log4j.rootLogger=debug, stdout  
  •   
  • log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
  • log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
  • log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n  

  • log4j.rootLogger=debug, stdout  
  •   
  • log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
  • log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
  • log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n  
log4j.rootLogger=debug, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n

shiro-first.ini
通过shiro-first.ini配置文件初始化SecurityManager环境,创建SecurityManager工厂。
配置MyEclipse支持ini,添加中文支持插件Properties Editor 地址是http://propedit.sourceforge.jp/eclipse/updates/
在MyEclipse配置后,在classpath创建shiro.ini配置文件,为了方便测试将用户名和密码配置在shiro-first.ini文件中

  • #对用户信息进行配置  
  • [users]  
  • #用户账号和密码  
  • zhangsan=123456  
  • lisi=654321  

  • #对用户信息进行配置  
  • [users]  
  • #用户账号和密码  
  • zhangsan=123456  
  • lisi=654321  
#对用户信息进行配置[users]#用户账号和密码zhangsan=123456lisi=654321


入门程序认证代码
[html]
  • // 用户登录和退出  
  •     @Test  
  •     public void testLoginAndLogout() {  
  •   
  •         // 创建SecurityManager工厂。通过ini配置文件创建securityManager  
  •         Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-first.ini");  
  •   
  •         // 创建SecurityManager  
  •         SecurityManager securityManager = factory.getInstance();  
  •   
  •         // 将securityManager设置到当前的运行环境中  
  •         SecurityUtils.setSecurityManager(securityManager);  
  •   
  •         // 从SecurityUtils中创建一个subject  
  •         Subject subject = SecurityUtils.getSubject();  
  •   
  •         // 在认证提交前准备token(令牌)  
  •         // 这里的账号和密码 将来是由用户输入进去的  
  •         UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");  
  •          
  •         //执行认证提交  
  •         try {  
  •             //执行认证提交  
  •             subject.login(token);  
  •         } catch (AuthenticationException e) {  
  •             e.printStackTrace();  
  •         }  
  •          
  •         // 是否认证通过  
  •         boolean isAuthenticated = subject.isAuthenticated();  
  •         System.out.println("是否认证通过:"+isAuthenticated);  
  •          
  •         //退出操作  
  •         subject.logout();  
  •          
  •         // 是否认证通过  
  •         isAuthenticated = subject.isAuthenticated();  
  •         System.out.println("是否认证通过:"+isAuthenticated);  
  •     }  

[java]
  • // 用户登录和退出  
  •     @Test  
  •     public void testLoginAndLogout() {  
  •   
  •         // 创建SecurityManager工厂。通过ini配置文件创建securityManager  
  •         Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-first.ini");  
  •   
  •         // 创建SecurityManager  
  •         SecurityManager securityManager = factory.getInstance();  
  •   
  •         // 将securityManager设置到当前的运行环境中  
  •         SecurityUtils.setSecurityManager(securityManager);  
  •   
  •         // 从SecurityUtils中创建一个subject  
  •         Subject subject = SecurityUtils.getSubject();  
  •   
  •         // 在认证提交前准备token(令牌)  
  •         // 这里的账号和密码 将来是由用户输入进去的  
  •         UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");  
  •          
  •         //执行认证提交  
  •         try {  
  •             //执行认证提交  
  •             subject.login(token);  
  •         } catch (AuthenticationException e) {  
  •             e.printStackTrace();  
  •         }  
  •          
  •         // 是否认证通过  
  •         boolean isAuthenticated = subject.isAuthenticated();  
  •         System.out.println("是否认证通过:"+isAuthenticated);  
  •          
  •         //退出操作  
  •         subject.logout();  
  •          
  •         // 是否认证通过  
  •         isAuthenticated = subject.isAuthenticated();  
  •         System.out.println("是否认证通过:"+isAuthenticated);  
  •     }  

认证执行流程
1.通过ini配置文件创建SecurityManager
2.创建token令牌,token中有用户提交的认证信息即用户名和密码
3.执行subject.login(token)方法提交认证,最终由securityManager通过Authenticator进行认证
4.Authenticator的实现ModularRealmAuthenticator调用realm从ini配置文件取出用户真实的账号和密码,这里使用的是iniRealm(shiro自带)
5.initRealm先根据先根据token中的账号去ini中查找账号,如果查找不到则给ModularRealmAuthenticator返回null,如果查到用户信息,就给ModularRealmAuthenticator返回用户信息(账号和密码)
6.ModularRealmAuthenticator接收IniRealm返回Authentication认证信息,如果返回的认证信息是null,ModularRealmAuthenticator抛出异常(org.apache.shiro.authc.UnknownAccountException)如果返回的认证信息不是null(说明inirealm找到了用户),对IniRealm返回用户密码 (在ini文件中存在)和 token中的密码 进行对比,如果不一致抛出异常(org.apache.shiro.authc.IncorrectCredentialsException)

常见的认证异常
UnknownAccountException
账号不存在异常如下:
org.apache.shiro.authc.UnknownAccountException:No account found for user…
I
ncorrectCredentialsException
当输入密码错误会抛此异常,如下:org.apache.shiro.authc.IncorrectCredentialsException:Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken -zhangsan, rememberMe=false] did not match the expected credentials.
更多如下:
DisabledAccountException(帐号被禁用)
LockedAccountException(帐号被锁定)
ExcessiveAttemptsException(登录失败次数过多)
ExpiredCredentialsException(凭证过期)等

小结:ModularRealmAuthenticator作用进行认证,需要调用realm查询用户信息(在数据库中存在用户信息)
ModularRealmAuthenticator进行密码对比(认证过程)。
realm:需要根据token中的身份信息去查询数据库(入门程序使用ini配置文件),如果查到用户返回认证信息,如果查询不到返回null。


点击下方标题查看相关学习资料

1 个回复

倒序浏览
谢谢小舞老师分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马