在上一篇文章《shiro认证流程源码分析--练气初期》当中,咱们简单分析了一下shiro的认证流程。不难发现,若是咱们须要使用其余数据源的信息完成认证操做,咱们须要自定义Realm继承AuthorizingRealm类,并实现两个方法,分别对应受权和认证。html
在这一篇文章当中,咱们将介绍如何自定义Realm对象,完成认证信息数据源的切换。java
/**自定义Realm对象 * @author 赖柄沣 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/4 11:00 */ public class MySqlRealm extends AuthorizingRealm { /**受权,今天暂不实现 * @author 赖柄沣 bingfengdev@aliyun.com * @date 2020-10-04 11:01:50 * @param principalCollection * @return org.apache.shiro.authz.AuthorizationInfo * @throws AuthenticationException * @version 1.0 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } /**认证 * @author 赖柄沣 bingfengdev@aliyun.com * @date 2020-10-04 11:01:50 * @param authenticationToken * @return org.apache.shiro.authz.AuthorizationInfo * @throws AuthenticationException * @version 1.0 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 1. 从token中获取用户名 String principal = (String) authenticationToken.getPrincipal(); //2. 根据用户名查询数据库(模拟) if (principal == "xiangbei") { AuthenticationInfo authInfo = new SimpleAuthenticationInfo("xiangbei","123",this.getName()); return authInfo; } return null; } }
/**认证管理器 * @author 赖柄沣 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/4 11:11 */ public class CurrentSystemAuthenticator { private DefaultSecurityManager securityManager; public CurrentSystemAuthenticator() { //建立安全管理器 securityManager = new DefaultSecurityManager(); //设置自定义realm this.securityManager.setRealm(new MySqlRealm()); //将安全管理器设置到安全工具类中 SecurityUtils.setSecurityManager(securityManager); } public void authenticate(String username,String password){ //获取当前登陆主题 Subject subject = SecurityUtils.getSubject(); //生成toeken UsernamePasswordToken token = new UsernamePasswordToken(username, password); //进行认证 try { subject.login(token); }catch (UnknownAccountException | IncorrectCredentialsException e) { System.out.println("用户名或密码不正确"); } //打印认证状态 if (subject.isAuthenticated()){ System.out.println(token.getPrincipal()+" 认证经过!"); }else { System.out.println(token.getPrincipal()+" 认证未经过!"); } } }
/**测试认证 * @author 赖柄沣 bingfengdev@aliyun.com * @version 1.0 * @date 2020/9/21 0:49 */ public class TestAuthenticator { private Authenticator authenticator=null; @Before public void init() { authenticator = new Authenticator(); } @Test public void testAuth(){ authenticator.authenticate("xiangbei","123"); } }
xiangbei 认证经过!
认证不经过的状况在shiro当中分为几种状况,具体能够查看个人上一篇文章《shiro认证流程源码分析--练气初期》 关于shiro认证异常的分析,经常使用的有以下几种:mysql
在实际项目中为了安全起见,帐户不正确和密码错误统一返回“用户名或密码不正确”相似的的提示,避免形成帐户泄露。git
下面针对这种状况给予演示github
/** * @author 赖柄沣 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/4 11:20 */ public class AuthcTest { private CurrentSystemAuthenticator authenticator; @Before public void init() { this.authenticator = new CurrentSystemAuthenticator(); } @Test public void testAuthc(){ this.authenticator.authenticate("xiangbei","13"); } }
用户名或密码不正确 xiangbei 认证未经过!
这一篇文章主要是带领你们了解一下如何经过自定义Realm对象完成shiro认证数据源的切换。对于MySQL的集成,咱们将在后面的文章当中集成SpringBoot时介绍。sql
下一篇文章将简单介绍shiro中的密码加密以及如何配置使用。数据库
本文所涉及的代码下载地址:https://github.com/code81192/art-demo/tree/master/shiro-authc-mysqlapache