网页制作模板的网站,东莞临时工最新招聘,wordpress清缓存,专业网站开发制作公司第一章 入门概述
1.概念
shiro是一个Java安全框架#xff0c;可以完成#xff1a;认证、授权、加密、会话管理、与web集成、缓存…
2.优势
● 易于使用#xff0c;构建简单 ● 功能全面 ● 灵活#xff0c;可以在任何应用程序环境中工作#xff0c;并且不需要依赖它们…第一章 入门概述
1.概念
shiro是一个Java安全框架可以完成认证、授权、加密、会话管理、与web集成、缓存…
2.优势
● 易于使用构建简单 ● 功能全面 ● 灵活可以在任何应用程序环境中工作并且不需要依赖它们 ● 高效支持web可以基于应用程序URL和Web协议创建灵活的安全策略 ● 兼容性强易于和其他框架和应用程序集成 ● 社区支持
3.与springsecurity的区别
● shiro需要和spring整合开发而springsecurity基于spring开发配合起来更便利 ● springsecurity比shiro功能丰富如安全维护 ● shiro配置和使用简单springsecurity较难 ● shiro依赖性低不需要任何框架和容器可以独立运行而springsecurity需要依赖spring容器 ● shiro可以工作于任何应用环境独立于容器
4.基本功能 Authentication身份认证/登录验证用户是否拥有对应的身份authorization权限验证验证用户是否拥有某个权限判断用户可以进行什么操作session management会话管理即用户登录后的一次会话在没有登出之前所有的信息都保存在会话中cryptography加密保证数据的安全比如密码加密存储数据库web supportweb支持集成web环境caching缓存比如用户登录后用户信息、角色和权限保存下来concurrency多线程并发验证比如在一个线程红开启另一个线程可以把权限自动传播过去Testing测试功能run as伪装用户remember me记住我
5.原理
shiro外部架构
subject对外API核心与应用代码直接交互的对象与subject的所有交互都会委托为securitymanager securitymanager安全管理器所有与安全相关的操作都会与securitymanager交互管理所有的subject是shiro的核心相当于spingmvc的dispatcherservlet的角色 realm从realm中获取安全数据信息用户、角色、权限
shiro内部架构 Subject任何可以与应用交互的“用户”SecurityManager 相当于 SpringMVC 中的 DispatcherServlet是 Shiro 的心脏 所有具体的交互都通过 SecurityManager 进行控制它管理着所有 Subject、且负责进 行认证、授权、会话及缓存的管理Authenticator负责 Subject 认证是一个扩展点可以自定义实现可以使用认证策略Authentication Strategy即什么情况下算用户认证通过了Authorizer授权器、即访问控制器用来决定主体是否有权限进行相应的操作即控制着用户能访问应用中的哪些功能Realm可以有 1 个或多个 Realm可以认为是安全实体数据源即用于获取安全实体的可以是 JDBC 实现也可以是内存实现等等由用户提供所以一般在应用中都需要实现自己的 RealmSessionManager管理 Session 生命周期的组件CacheManager缓存控制器来管理如用户、角色、权限等的缓存的因为这些数据 基本上很少改变放到缓存中后可以提高访问的性能Cryptography密码模块Shiro 提高了一些常见的加密组件用于如密码加密/解密。
第二章 基本使用
1.环境搭建 ● 引入依赖
dependenciesdependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-core/artifactIdversion1.9.0/version/dependencydependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.2/version/dependency
/dependencies● ini文件src/main/resources/shiro.ini
[users]
zhangsanz3
lisil42.登录认证
概念 ① 身份验证一般需要提供如身份ID等一些标识信息来表明登录者的身份如提供email用户名/密码来证明 ② 在shiro中用户需要提供principals身份和credentials证明给shiro从而应用能验证用户身份 ③ principals身份即主体的标识属性可以是任何属性如用户名、邮箱等唯一即可。一个主体可以有多个principals但只有一个Primary principals一般是用户名/邮箱/手机号 ④ credentials证明/凭证即只有主体知道的安全值如密码/数字证书等 最常见的principals和credentials组合就是用户名/密码 流程 ① 收集用户身份/凭证即如用户名/密码 ② 调用 Subject.login 进行登录如果失败将得到相应 的 AuthenticationException异常根据异常提示用户 错误信息否则登录成功 ③ 创建自定义的 Realm 类继承 org.apache.shiro.realm.AuthenticatingRealm类,实现 doGetAuthenticationInfo() 方法 实例
public class ShiroRun {public static void main(String[] args) {//1.初始化获取securitymanagerIniSecurityManagerFactory factory new IniSecurityManagerFactory(classpath:shiro.ini);SecurityManager securityManager factory.getInstance();SecurityUtils.setSecurityManager(securityManager);//2.获取subject对象Subject subject SecurityUtils.getSubject();//3.创建token对象web应用用户名密码从页面传递AuthenticationToken token new UsernamePasswordToken(zhangsan, z3);//4.完成登录try {subject.login(token);System.out.println(login successful);} catch (UnknownAccountException e) {e.printStackTrace();System.out.println(用户不存在);}catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println(密码错误);}catch (AuthenticationException e) {e.printStackTrace();System.out.println(登录失败);}}
}3.授权
① 授权也叫访问控制即在应用中控制谁访问哪些资源如访问页面/编辑数据/页面 操作等。在授权中需了解的几个关键对象主体Subject、资源Resource、权限 Permission、角色Role ② 主体(Subject)访问应用的用户在 Shiro 中使用 Subject 代表该用户。用户只有授权 后才允许访问相应的资源 ③ 资源(Resource)在应用中用户可以访问的 URL比如访问 JSP 页面、查看/编辑 某些 数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问 ④ 权限(Permission)安全策略中的原子授权单位通过权限我们可以表示在应用中用户 有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源如访问用 户列表页面查看/新增/修改/删除用户数据即很多时候都是CRUD增查改删式权限控 制等。权限代表了用户有没有操作某个资源的权利即反映在某个资源上的操作允不允许 ⑤ Shiro 支持粗粒度权限如用户模块的所有权限和细粒度权限操作某个用户的权限 即实例级别的 ⑥ 角色(Role)权限的集合一般情况下会赋予用户角色而不是权限即这样用户可以拥有 一组权限赋予权限时比较方便。典型的如项目经理、技术总监、CTO、开发工程师等都是角色不同的角色拥有一组不同的权限 授权方式
编程式subject.hasRole(admin)注解式RequiresRoles(admin)jsp/gsp标签shiro:hasRole nameadmin/shiro:hasRole
授权流程
首先调用Subject.isPermitted*/hasRole*接口其会委托给SecurityManager而SecurityManager接着会委托给 AuthorizerAuthorizer是真正的授权者如果调用如isPermitted(“user:view”)其首先会通过PermissionResolver把字符串转换成相应的Permission实例在进行授权之前其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限Authorizer会判断Realm的角色/权限是否和传入的匹配如果有多个Realm会委托给ModularRealmAuthorizer进行循环判断如果匹配如isPermitted*/hasRole* 会返回 true否则返回false表示授权失败
实例
1.给shiro.ini增加角色配置
[users]
fateadmin,role1,role2
fuck1234562.增加权限配置
[roles]
role1user:insert,user:select3.测试代码
public static void main(String[] args) {//1.初始化获取securitymanagerIniSecurityManagerFactory factory new IniSecurityManagerFactory(classpath:shiro.ini);SecurityManager securityManager factory.getInstance();SecurityUtils.setSecurityManager(securityManager);//2.获取subject对象Subject subject SecurityUtils.getSubject();//3.创建token对象web应用用户名密码从页面传递AuthenticationToken token new UsernamePasswordToken(zhangsan, z3);//4.完成登录try {subject.login(token);System.out.println(login successful);//5.判断角色boolean hasRole subject.hasRole(role1);System.out.println(是否拥有role1角色 hasRole);//6.判断权限boolean permitted subject.isPermitted(user:insert);System.out.println(是否拥有此权限 permitted);//也可以用checkPermission方法但没有返回值没权限抛AuthenticationExceptionsubject.checkPermission(user:update);} catch (UnknownAccountException e) {e.printStackTrace();System.out.println(用户不存在);} catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println(密码错误);} catch (AuthenticationException e) {e.printStackTrace();System.out.println(登录失败);}
}4.加密 Shiro内嵌很多常用的加密算法比如MD5加密
public class ShiroMD5 {public static void main(String[] args) {//密码明文String password admin;//使用MD5加密Md5Hash md5Hash new Md5Hash(password);System.out.println(md5加密 md5Hash);//带盐的md5加密盐就是在密码明文后拼接新字符串然后再进行加密Md5Hash md5Hash1 new Md5Hash(password, salt);System.out.println(带盐的md5加密 md5Hash1.toHex());//为了保证安全避免被破解还可以多次迭代加密保证数据安全Md5Hash md5Hash2 new Md5Hash(password, salt, 3);System.out.println(带盐的3次迭代加密 md5Hash2);//使用父类进行加密SimpleHash simpleHash new SimpleHash(MD5, password, salt, 3);System.out.println(父类带盐的3次加密 simpleHash);}
}5.自定义登录认证 Shiro 默认的登录认证是不带加密的如果想要实现加密认证需要自定义登录认证 自定义Realm
public class MyRealm extends AuthenticatingRealm {//自定义登录认证方法shiro的login方法的底层会调用该类的认证方法进行认证//需要配置自定义的realm生效应该在ini文件中配置如果有springboot框架也可以在Springboot中进行配置//该方法只是获取进行对比的信息认证逻辑还是按照shiro的底层认证逻辑来完成protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//1.获取身份信息String principal authenticationToken.getPrincipal().toString();//2.获取凭证信息String password new String((char[]) authenticationToken.getCredentials());System.out.println(认证的用户信息: principal --- password);//3.获取数据库中存储的用户信息if(principal.equals(zhangsan)){//3.1数据库中存储的加盐3次迭代的密码String pwdInfo b073e9301c412431159e7075340c4c66;//4.创建封装校验逻辑的对象封装数据返回AuthenticationInfo info new SimpleAuthenticationInfo(authenticationToken.getPrincipal(),pwdInfo,ByteSource.Util.bytes(salt),authenticationToken.getPrincipal().toString());return info;}return null;}
}添加配置信息让shiro知晓你使用的是自定义的Realm
[main]
#在shiro.ini中添加配置信息
md5CredentialsMatcherorg.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations3
myrealmcom.atguigu.shirotest.MyRealm
myrealm.credentialsMatcher$md5CredentialsMatcher
securityManager.realms$myrealm[users]
zhangsan7174f64b13022acd3c56e2781e098a5f,role1,role2
lisil4 [roles]
role1user:insert,user:select第三章 与springboot整合
框架整合
1.引入依赖
parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.2.1.RELEASE/version
/parent
dependenciesdependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-spring-boot-web-starter/artifactIdversion1.9.0/version/dependency!--mybatis-plus--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.0.5/version/dependency!--mysql--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.46/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency
/dependencies2.配置文件
# mybatis配置
mybatis-plus:configuration:# 日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:mapper/ *.xmlspring:
# 数据库配置datasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/shirodb?characterEncodingutf-8useSSLfalsepassword: rootusername: root
# json格式jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8shiro:
# 登录接口loginUrl: /myController/login3.自定义realm
Component
public class MyRealm extends AuthorizingRealm{Autowiredprivate UserService userService;//自定义授权方法Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}//自定义登录认证方法Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//1.获取用户身份信息String name authenticationToken.getPrincipal().toString();//2.调用业务层获取用户信息(数据库)User user userService.getUserInfoByName(name);//3.非空判断将数据封装返回if(user ! null){AuthenticationInfo info new SimpleAuthenticationInfo(authenticationToken.getPrincipal(),user.getPwd(),ByteSource.Util.bytes(salt),authenticationToken.getPrincipal().toString());return info;}return null;}
}4.配置类
Slf4j
Configuration
public class ShiroConfig {Autowiredprivate MyRealm myRealm;//配置SecurityManagerBeanpublic DefaultWebSecurityManager defaultWebSecurityManager(){//1.创建defaultWebSecurityManager 对象DefaultWebSecurityManager defaultWebSecurityManager new DefaultWebSecurityManager();//2.创建加密对象设置相关属性HashedCredentialsMatcher matcher new HashedCredentialsMatcher();//2.1 采用md5加密matcher.setHashAlgorithmName(md5);//2.2 迭代加密次数matcher.setHashIterations(3);//3.将加密对象存储到myRealm中myRealm.setCredentialsMatcher(matcher);//4.将myRealm存入defaultWebSecurityManager 对象defaultWebSecurityManager.setRealm(myRealm);//5.返回return defaultWebSecurityManager;}//配置Shiro内置过滤器拦截范围Beanpublic DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition new DefaultShiroFilterChainDefinition();
// 设置不认证就可以访问的资源defaultShiroFilterChainDefinition.addPathDefinition(/myController/userLogin,anon);defaultShiroFilterChainDefinition.addPathDefinition(/login,anon);
// 设置需要进行登录认证的拦截范围defaultShiroFilterChainDefinition.addPathDefinition(/**,authc);return defaultShiroFilterChainDefinition;}
}5.编写控制类
Controller
RequestMapping(myController)
public class MyController{GetMapping(userLogin)ResponseBobypublic String userLogin(String name,String pwd){//1.获取subject对象Subject subject SecurityUtils.getSubject();//2.封装请求数据到tokenAuthenticationToken token new UsernamePasswordToken(name,pwd);//3.调用login方法进行登录认证try{ subject.login(token);return 登录成功;}catch(AuthenticationException e){e.printStackTrace();System.out.println(登录失败);return 登录失败;}
}