Realm简介
Realm的作用是用来验证用户提供的登录信息是否正确。如果正确,则返回一个AuthenticationInfo
对象,该对象代表一个已经通过验证的用户对象。shiro中有一个对象的名称和AuthenticationInfo相似,那就是AuthenticationToken
。两者的区别是:AuthenticationInfo是已经通过验证的对象,而AuthenticationToken是还没有通过验证的对象。通常,Realm中提供验证的后端数据来自数据库,也可以是其他形式,例如xml数据,或者json数据。
实现自定义Realm
有两种方式可以实现自定义Realm,第一种是实现Realm
接口,第二种是继承AuthorizingRealm
。不同的是第一种方式只能验证用户信息,而第二种方式还可以授予用户权限。
实现Realm
创建自定义Realm只需要实现Realm接口即可,该接口提供了三个必须实现的方法。分别是getName()
,supports()
和getAuthenticationInfo()
,账户验证的逻辑在getAuthenticationInfo()方法中实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public class MyRealm implements Realm { @Override public String getName() { return getClass().getName(); } @Override public boolean supports(AuthenticationToken token) { //是否支持这种验证方式。如果不是基于用户名和密码的验证则不支持 return token instanceof UsernamePasswordToken; } @Override public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //获取用户名,通常是用户提交的表单 String username = (String) token.getPrincipal(); //获取密码 String password = new String((char[])token.getCredentials()); if (!"marry".equals(username)){ throw new UnknownAccountException(); } if (!"123".equals(password)){ throw new IncorrectCredentialsException(); } //验证通过则返回账户信息 return new SimpleAuthenticationInfo(username, password, getName()); } } |
继承AuthorizingRealm
AuthorizingRealm类需要实现的方法有两个,分别是:
- doGetAuthenticationInfo
- doGetAuthorizationInfo
两个方法的作用分别是验证用户信息和获取用户权限。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public class MyRealm extends AuthorizingRealm{ /** * 获取权限信息 * @param principals * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } /** * 验证账号 * @param token * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //获取用户名,通常是用户提交的表单 String username = (String) token.getPrincipal(); //获取密码 String password = new String((char[])token.getCredentials()); if (!"marry".equals(username)){ throw new UnknownAccountException(); } if (!"123".equals(password)){ throw new IncorrectCredentialsException(); } //验证通过则返回账户信息 return new SimpleAuthenticationInfo(username, password, getName()); } } |
配置Ini文件
使用自定义Realm的时候,配置文件的设置顺序应该注意,[users]
的位置必须在自定义Realm的后面,如果[users]放在自定义Realm的前面,这个自定义的Realm就不会生效。
1 2 3 4 5 |
myRealm=cn.sharpcode.realm.MyRealm securityManager.realms=$myRealm [users] jack=123 |
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@Test public void testCustomRealm(){ IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini"); SecurityManager manager = factory.getInstance(); SecurityUtils.setSecurityManager(manager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("marry", "123"); try{ subject.login(token); } catch (AuthenticationException e){ e.printStackTrace(); } Assert.assertEquals(true, subject.isAuthenticated()); } |
转载请注明:Pure nonsense » shiro使用自定义Realm