sdsd安全框架的分类:
在项目中,我所用到的安全框架有Shiro,以及spring Security,对于security 是有局限性的,它是基于Spring 而且比较笨重,相比Shiro就比较轻量级了,没有这么局限,但是在安全的程度没security这么强,所以要根据自己的项目去选择什么安全框架;
在这里我只是讲Shiro,因为日常开发用它已经足够了
Shiro是什么?
对于这点我做个简单的讲解,它可以执行身份验证,授权以及加密和会话管理。我们通过它来保护我们的应用程序,具体大家可以去官网看。
Shiro组成
Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份;
Authorization::授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Management:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web 支持,可以非常容易的集成到 Web 环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色 / 权限不必每次去查,这样可以提高效率;
Concurrency:shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
PS:上面看完了记住4大基石(Authentication,Authorzation,Session Management,Cryprography)
还有3大组件:

Subject:主体,不一定指人,与当前应用交互的任何东西如爬虫等程序,它是抽象概念,所有耳的Subject都绑定到SecurityManager,反正Subject的所有交互都会交给安全管理器,所有安全管理器才是真正的执行者。
SecurityManager:安全管理器,只要和安全挂钩的都会和安全管理器挂钩,所有它很重要,它管理着所有的Subject,我们可以把看做前端控制器。

Realm:域,Shiro从域获取安全数据(用户,角色,权限),说通俗点就是,在认证的时候安全管理器需要验证,这时候就会去域中获取用户进行身份的比较,时候合法,在进行操作,我们可以把它看做安全数据源。
下面张比较详细:

实际实操
说了理论,下面上实际操作,我会以springBoot来做伪代码
依赖
我们可以去官网看它相关的依赖
<!-- Shiro依赖 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.5.2</version> </dependency> <!-- 引入Thymeleaf模板引擎 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- Spring Data JPA依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- MySQL的JDBC数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.19</version> </dependency>
讯享网
题外话:
我们可以在yml中添加
讯享网spring:
#使用Thymeleaf模板引擎
thymeleaf:
mode: HTML5
encoding: UTF-8
#使用Thymeleaf模板引擎,关闭缓存
cache: false
servlet:
content-type: text/html
# JPA数据库连接信息
datasource:
url: jdbc:mysql://localhost:3306/db_admin?useSSL=false&
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
database: MYSQL
show-sql: true
open-in-view: true
properties:
hibernate:
#使用延时加载时控制Session的生命周期
enable_lazy_load_no_trans: true
dialect: org.hibernate.dialect.MySQL5Dialect
ddl-auto: update
在实体中
/ *标识主体 / @Entity / *免于Get,和Set / @Data / *应数据库 / @TableName("yun_worker") public class Worker{ //作为主键 @TableId private String workId; / * 劳工姓名 身份证上姓名 */ private String workName; / * 身份证号 */ private String workIdentiId; / * 项目名称 */ //表中不存在的字段 @TableField(exist = false) private String projectName; .... }
回归正题
创建ShiroRealm,也就是域
讯享网public class ShiroRealm extends AuthorizingRealm{ / * 权限配置 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //创建Shiro授权对象 SimpleAuthorizationInfo authorization = new SimpleAuthorizationInfo(); //获取用户信息 Worker worker= (Worker) principals.getPrimaryPrincipal(); //遍历角色与权限 List<Worker> workerList = worker.getRole(); if (workerList!= null && workerList.size() > 0){ //使用Lambda表达式,此特性子啊jdk1.8就有了 workerList .forEach(role -> { //添加角色信息 //添加权限信息 List<PermissionInfo> permissionInfoList = role.getPermissionInfoList(); if (permissionInfoList != null && permissionInfoList.size() > 0) { } }); } return authorization; } / * 进行身份认证,判断用户名密码是否匹配正确 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //获取用户的输入的账号 String wokerName = (String) token.getPrincipal(); //System.out.println("身份:"+wokerName ); //System.out.println("凭证:"+token.getCredentials()); if (wokerName == null || wokerName .length() == 0){ return null; } //获取用户信息 Worker worker =dao层(userName); if (worker == null){ //未知账号 throw new UnknownAccountException(); } //判断账号是否被锁定,状态(0:禁用;1:锁定;2:启用) if(userInfo.getState() == 0){ //帐号禁用 throw new DisabledAccountException(); } if (userInfo.getState() == 1){ //帐号锁定 throw new LockedAccountException(); } //验证 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( //用户名, //密码, ByteSource.Util.bytes(Salt), //盐 //realm name ); return authenticationInfo; } //DisabledAccountException(禁用的帐号) //UnknownAccountException(错误的帐号) //ExcessiveAttemptsException(登录失败次数过多) //LockedAccountException(锁定的帐号) }
在创建配置类ShiroConfig吗,里面有很多方法,采取你所需要的
@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean ShiroFilterFactoryBean (SecurityManager securityManager) { //shiroFilter ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //拦截器. Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); // 配置不需要权限的资源 filterChainDefinitionMap.put("/login", "anon"); //配置退出过滤器,退出代码Shiro已经替我们实现 //filterChainDefinitionMap.put("/logout", "logout"); //过滤链定义,从上向下顺序执行,/放在最下边; //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> filterChainDefinitionMap.put("/", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login"页面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index"); //未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } / * 凭证匹配器 * 密码校验交给Shiro的SimpleAuthenticationInfo进行处理 */ @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5");//散列算法:这里使用MD5算法; hashedCredentialsMatcher.setHashIterations(3);//散列的次数.自己说的算; return hashedCredentialsMatcher; } @Bean public ShiroRealm myShiroRealm() { ShiroRealm myShiroRealm = new ShiroRealm(); myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; } @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); return securityManager; } @Bean(name = "simpleMappingExceptionResolver") public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() { SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理 mappings.setProperty("UnauthorizedException", "403"); r.setExceptionMappings(mappings); r.setDefaultErrorView("error"); r.setExceptionAttribute("ex"); // 缺省值"exception" return r; } / * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能 */ @Bean public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager()); return authorizationAttributeSourceAdvisor; } }
这就是我对Shiro框架的理解

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/20328.html