shiro大致介绍
shiro是什么
shiro是apache组织下维护的一个安全框架.
1. 帮我们做认证.
2. 帮我们做权限的校验.
3. 帮我们做密码加密加盐.
4. shiro可以自定义Session.
5. shiro可以帮我们缓存用户权限信息.
6. shiro还一共了各种认证/授权的校验方式,针对项目类型可以自由选择.
shiro和Spring security比较
- shiro可以脱离Spring单独使用. Spring security无法脱离Spring单独使用
- shiro是一款很轻的安全框架,学习简单. spring security相对更重,学习成本比较高.
- shiro关于全县控制的粒度相对更粗. spring security对权限的控制很细
- spring之前的官网用的是shiro.
shiro的架构
shiro的入门
创建项目
导入依赖
shiro-core-1.4.0
simpleRealm,iniRealm,JdbcRealm创建分为几步,大致相同
创建Realm对象
创建SecurityManager对象
2.1 给Security Manager对象设置创建好的Realm对象
生成Subject主题
3.1 给SecurityUtils设置上securityManager对象
3.2 用SecurityUtils创建subject主体
由主体发起认证请求 subject.login((“username”,“password”));
如果用户名或密码错误shiro直接抛出异常。
用户名错误UnKnowAccountException(账户异常)
密码错误IncorreCredentialsException(凭据异常|密码错误)
判断是否登陆过
subjec.isAuthentication
角色的授权认证
subject.checkRoles
角色的权限校验
subject.checkPremissions
simpleRealm
// 1. 创建SimpleRealm对象.
SimpleAccountRealm realm = new SimpleAccountRealm();
realm.addAccount("admin", "admin");
//创建创建SecurityManager对象
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(realm);
//创建Subject主题
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
//4. 由主体发起认证请求.
subject.login(new UsernamePasswordToken("admin", "admin"));
// 如果用户名或密码错误,shiro直接抛出异常.
// 用户名错误 -> UnknowAccountException 密码错误 -> IncorrectCredentialsException
//判断是否验证过
if(subject.isAuthenticated()){
System.out.println("登陆成功");
}
//角色授权
boolean lala = subject.hasRole("lala");
System.out.println(lala);
iniRealm
shiro.ini
[users]
admin=admin,超级管理员,普通用户
[roles]
超级管理员=user:select,user:insert,user:delete,user:update
普通用户=user:select,user:insert
//创建iniRealmTest对象
IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
//创建SecurityManager对象
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(iniRealm);
//创建subjec主体
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
//由主体发送请求
subject.login(new UsernamePasswordToken("admin","admin"));
//判断是否校验过
if(subject.isAuthenticated()){
System.out.println("success");
}
//角色授权
subject.checkRoles("超级管理员","普通用户");
subject.checkPermissions("user:insert","user:delete");
jdbcRealm
//1.创建Realm
JdbcRealm jdbcRealm = new JdbcRealm();
// 1.1创建数据源
DruidDataSource ds=new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql:///shiro");
ds.setUsername("root");
ds.setPassword("123456");
//导入数据源(切记,老忘)
jdbcRealm.setDataSource(ds);
//1.2手动创建sql
jdbcRealm.setAuthenticationQuery("select password from user where username=?");
//手动开启权限校验
jdbcRealm.setPermissionsLookupEnabled(true);
//创建ScurityManager
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(jdbcRealm);
//创建subjec主体
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
//主题提交认证请求
subject.login(new UsernamePasswordToken("admin","admin"));
if(subject.isAuthenticated()){
System.out.println("success");
}
//角色得授权
subject.checkRoles("普通用户");
//权限的授权
subject.checkPermissions("user:select");
CustomRealm自定义
-
自定义认证
//获取用户输入的用户名 String username = (String) token.getPrincipal(); //根据用户名查询用户信息(模拟数据库操作) User user = this.selectUserByUserName(username); if(user==null){ return null; } //4. 将正确的user对象和密码封装到AuthenticationInfo对象中. SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), "realName=DN"); //5. 将盐设置到info对象中 info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt())); return info;
实现密码的加密和密码的加盐. 密码加密: 在CustomRealm中,添加代码块,指定加密方式和加密次数. // 设置MD5加密1024次. { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); matcher.setHashAlgorithmName("MD5"); matcher.setHashIterations(1024); this.setCredentialsMatcher(matcher); } 在doGetAuthenticationInfo方法中,返回info对象之前.添加以下操作. info.setCredentialsSalt(ByteSource.Util.bytes(String salt));
-
自定义授权
//获取用户输入的用户名 User user = (User) principals.getPrimaryPrincipal(); String username = user.getUsername(); //根据用户名查询全部角色(模拟数据库操作) Set<String> allRoles = this.findAllRoleByUseName(username); //根据allRoles查询全部权限 Set<String> allPermissions = this.findAllPermissionsByUsername(allRoles); //4. 创建返回结果info,并封装角色和权限. SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(allRoles); info.setStringPermissions(allPermissions); return info;
shiro-Spring整合细节
创建项目
导入依赖
<!--spring--> spring-context spring-aspects spring-jdbc spring-webmvc spring-test <!--shiro整合spring--> shiro-core shiro-web shiro-spring <!--web--> javax.servlet.jsp-api javax.servlet-api //记得添加限定<scope>provided</scope <!--通用--> junit druid mysql-connector-java lombok
web.xml配置