shiro初体验,蹒跚学步
2020-02-29 本文已影响0人
Ktry
1-登录登出
- shiro.ini
[users]
zhangsan=666
lisi=456
- ShiroTest
@Test
public void testLogin() throws Exception{
//创建工厂对象,加载配置文件
IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro.ini");
//通过工厂对象创建securityManager对象
SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
//将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
SecurityUtils.setSecurityManager(securityManager);
//创建当前登录的主体(此时主体未认证)
Subject subject = SecurityUtils.getSubject();
//收集主体登录的数据(账号密码)
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
//登录操作
try {
subject.login(token);
}catch (Exception e){
//登录失败
e.printStackTrace();
}
//判断是否登录成功
System.out.println(subject.isAuthenticated());
//登出操作
subject.logout();
//判断是否登录成功
System.out.println(subject.isAuthenticated());
}
- 异常解析
UnknownAccountException====>账号有误
IncorrectCredentialsException====> 密码有误
2-自定义realm
- 继承AuthorizingRealm,重写三个方法
public class MyRealm extends AuthorizingRealm {
@Override
public String getName() {
return "MyRealm";
}
//授权操作
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
//认证操作
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//token表示登录时封装的UsernamePasswordToken
String usernam = (String) token.getPrincipal();
//假设数据库找不到这个用户名
if(!usernam.equals("zhangsan")){
return null;
}
String password = "666";
//simpleAuthenticationInfo表示realm登录比对信息,
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, getName());
return simpleAuthenticationInfo;
}
}
- 配置ini文件,指定使用自定义realm
myRealm= com.wu.realm.MyRealm
securityManager.realms=$myRealm
- 加载配置文件,执行登录操作
@Test
public void testLoginByRealm() throws Exception{
//创建工厂对象,加载配置文件
IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
//通过工厂对象创建securityManager对象
SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
//将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
SecurityUtils.setSecurityManager(securityManager);
//创建当前登录的主体(此时主体未认证)
Subject subject = SecurityUtils.getSubject();
//收集主体登录的数据(账号密码)
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
//登录操作
try {
subject.login(token);
}catch (Exception e){
e.printStackTrace();
//登录失败
}
//判断是否登录成功
System.out.println(subject.isAuthenticated());
//登出操作
subject.logout();
//判断是否登录成功
System.out.println(subject.isAuthenticated());
}
3-加密realm
- 使用MD5散列
@Test
public void testMD5(){
//模拟未加密的密码
String password = "666";
//使用MD5散列后的结果
Md5Hash md5Hash = new Md5Hash(password);
//使用MD5加盐散列后的结果
md5Hash = new Md5Hash(password,"zhangsan");
//使用MD5加盐散列3次后的结果
md5Hash = new Md5Hash(password,"zhangsan",3);
//输出结果 cd757bae8bd31da92c6b14c235668091
System.out.println(md5Hash);
}
- 新建realm,继承AuthorizingRealm,重写三个方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//token表示登录时封装的UsernamePasswordToken
String usernam = (String) token.getPrincipal();
//假设数据库找不到这个用户名
if(!usernam.equals("zhangsan")){
return null;
}
//模拟数据库中加密之后的密码
String password = "cd757bae8bd31da92c6b14c235668091";
//simpleAuthenticationInfo表示realm登录比对信息 ----------加上盐值
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, ByteSource.Util.bytes("zhangsan"), getName());
return simpleAuthenticationInfo;
}
- 配置ini文件,指定使用自定义realm
[main]
#定义密码凭证器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#设置散列算法
credentialsMatcher.hashAlgorithmName=md5
#设置散列次数
credentialsMatcher.hashIterations=3
#将凭证匹配器设置到realm
myRealm= com.wu.realm.PasswordRealm
myRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$myRealm
- 加载配置文件,执行登录操作
@Test
public void testLoginByPasswordRealm() throws Exception{
//创建工厂对象,加载配置文件
IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-cryptography.ini");
//通过工厂对象创建securityManager对象
SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
//将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
SecurityUtils.setSecurityManager(securityManager);
//创建当前登录的主体(此时主体未认证)
Subject subject = SecurityUtils.getSubject();
//收集主体登录的数据(账号密码)
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
//登录操作
try {
subject.login(token);
}catch (Exception e){
e.printStackTrace();
//登录失败
}
//判断是否登录成功
System.out.println(subject.isAuthenticated());
//登出操作
subject.logout();
//判断是否登录成功
System.out.println(subject.isAuthenticated());
}
4-权限
- 继承AuthorizingRealm,重写三个方法
@Override
public String getName() {
return "SuRealm";
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//获取前端传来的用户名
String userName = (String) principals.getPrimaryPrincipal();
//通过用户名去数据库查询其权限(省略------ 。。。。模拟数据)
Set<String> perms = new HashSet<String>();
perms.add("user:add");
perms.add("user:modify");
perms.add("user:delete");
//通过用户名去数据库查询其角色(省略------ 。。。。模拟数据)
Set<String> roles = new HashSet<String>();
roles.add("administrator");
roles.add("seller");
roles.add("buyer");
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roles);
simpleAuthorizationInfo.setStringPermissions(perms);
return simpleAuthorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//token表示登录时封装的UsernamePasswordToken
String usernam = (String) token.getPrincipal();
//假设数据库找不到这个用户名
if(!usernam.equals("zhangsan")){
return null;
}
//模拟数据库中加密之后的密码
String password = "cd757bae8bd31da92c6b14c235668091";
//simpleAuthenticationInfo表示realm登录比对信息,
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, ByteSource.Util.bytes("zhangsan"), getName());
return simpleAuthenticationInfo;
}
- 配置ini文件,指定使用自定义realm
[main]
#定义密码凭证器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#设置散列算法
credentialsMatcher.hashAlgorithmName=md5
#设置散列次数
credentialsMatcher.hashIterations=3
#将凭证匹配器设置到realm
myRealm= com.wu.realm.SuRealm
myRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$myRealm
-
执行登录操作,测试权限
1,代码实现
@Test public void testLoginByPasswordRealm() throws Exception{ //创建工厂对象,加载配置文件 IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-cryptography-su.ini"); //通过工厂对象创建securityManager对象 SecurityManager securityManager = iniSecurityManagerFactory.getInstance(); //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象 SecurityUtils.setSecurityManager(securityManager); //创建当前登录的主体(此时主体未认证) Subject subject = SecurityUtils.getSubject(); //收集主体登录的数据(账号密码) UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666"); //登录操作 try { subject.login(token); }catch (Exception e){ e.printStackTrace(); //登录失败 } //判断是否登录成功 System.out.println(subject.isAuthenticated()); //测试权限 需求:输出"hello",需要"user:add"权限 if(subject.isPermitted("user:add")){ System.out.println("hello"); }else {System.out.println("没有权限");} //表示一个个判断,返回bool数组 boolean[] booleans = subject.isPermitted("","",""); subject.isPermitted(new ArrayList<Permission>()); //测试角色 判断是否具有某个角色 subject.hasRole(""); //一个一个判断,是否具有某个角色 subject.hasRoles(new ArrayList<String>()); //判断是否具有所有角色 subject.hasAllRoles(new ArrayList<String>()); //登出操作 subject.logout(); //判断是否登录成功 System.out.println(subject.isAuthenticated()); }
2,注解实现
@RequiresRoles("")
public void test1(){}
待续。。。