Shiro 简单的JavaDemo
普通的Java项目实现shiro的简单demo需要ini配置文件及单元测试模块
一.无自定义Realm实现
1.ini配置
[users]
zhanggouzi =123 ,user
root =456 ,admin
[roles]
admin = student:*
user = student:list
2.单元测试模块
public static void main(String[] args) {
//1.用工厂读取文件实例化一个SecurityManager
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:asd.ini");
SecurityManager securityManager = factory.getInstance();
//设置securityManager作为一个单例放到JVM内存空间中
SecurityUtils.setSecurityManager(securityManager);
//subject 相当于用户主题
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhanggouzi", "123");
//下面的login则为模拟用户的登录
subject.login(token);
//判断账号密码是否正确. 认证~
System.out.println(subject.isAuthenticated());
//查看授权,是否有相应的权限
System.out.println(subject.isPermitted("student:list"));
System.exit(0);
}
小结: 模拟shiro框架实现登录需要一个securityManager接口. 实现这个接口需要用到Ini
SercurityManagerFactory . securityManager这个接口实现类负责管理登录和授权.再有SecurityUtils工具类获取subject类似于用户主体模拟登录.
二.自定义Realm实现
1.ini配置文件------------这里加上了加盐的MD5算法
[main]
#配置认证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName=md5
credentialsMatcher.hashIterations=1
#一定要先定义customRealm再使用
customRealm=com.sp.realm.CustomRealm
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm
2.ini配置文件关联的自定义realm代码块(后续web的认证和授权会对数据库进行访问)
public class CustomRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//上面的传参 principals 与token类似, principals.getprimaryprincipal()可以是通过了认证后被赋予的对象
Set<String> roles = new HashSet<>();
roles.add("student");
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addStringPermissions(roles);
return simpleAuthorizationInfo;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String principal = (String) token.getPrincipal();
//这里的判断模拟从数据库查找niubi这个用户,有则再获得其密码,return到上一级来判断密码是否正确
if (!principal.equals("niubi")) {
//这里为模拟数据库中无法查找到niubi这个用户,return null则会报unkownAccount异常
return null;
}
String password = "c0f51004450a19e3b77001c56c3dc113";
String salt = "aluba";
//return SimpleAuthenticationInfo对象到上一级会进行数据库和用户输入的密码校验,如果密码不正确则会报验证密码不正确的异常
ByteSource credentialsSalt = ByteSource.Util.bytes(salt.getBytes());
return new SimpleAuthenticationInfo(principal, password, credentialsSalt,"aa");
}
}
3.demo模块
@Test
public void testCustomRealm(){
//先通过读取配置实现一个SecurityManager的实现工厂,在由这个工厂得到SecurityManager实例
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:myRealm.ini");
SecurityManager securityManager = factory.getInstance();
//通过SecurityUtils 加载securityManager到JVM内存空间中 (这个后续应该是加载到spring容器或者应用程序等类似于HttpSession中)
SecurityUtils.setSecurityManager(securityManager);
//模拟登陆,得到一个登陆的subject ,这个类似于用户主体
Subject subject = SecurityUtils.getSubject();
//模拟用户输入的令牌,一个为账号名,另外的为密码
UsernamePasswordToken token = new UsernamePasswordToken("niubi", "666");
//模拟登陆
subject.login(token);
System.out.println(subject.isAuthenticated());
//查看授权
System.out.println(subject.isPermittedAll("student"));
}
小结:配置自定义Realm需要声明customRealm=com.sp.realm.CustomRealm,并且把这个Realm赋到SecurityManager中securityManager.realms=$customRealm,
总结
SecurityManager :核心,里面管理realm认证和授权的运行,并且还有缓存.记住我的一系列功能
Realm:自定义Realm后续可以管理数据库,判断用户输入的账户是否存在,(密码是否正确则是传密码到上一层,由上一层处理). 从数据库中查找用户拥有的权限,并进行授权
IniSecurityManagerFactory:实现SecurityManager的工厂
SecurityUtils:shiro的获取主体以及设置SecurityManager到session模块的工具类
Token: 令牌, 内含用户输入的账号以及密码
subject:类似用户主体属性,