Shiro:初识Shiro及简单尝试
Shiro
一、什么是Shiro
Apache Shiro是Java的一个安全(权限)框架
作用:认证、授权、加密、会话管理、与web集成、缓存等
下载地址:http://shiro.apache.org/download.html
二、Shiro的架构
1)subject:可以与应用交互的“用户”
2)SecurityManager:相当于SpringMVC中的DispatcherServlet;是Spring的心脏,交互都由其控制。管理所有的subject且负责进行认证、授权、会话及缓存的管理。
3)Authenticator:负责subject认证,是一个扩展点,可自定义实现;可以使用认证策略(Authentication Strategy)即什么情况下算用户通过了认证。
4)Authorizer:授权器。决定是否有权限进行相应的操作。控制用户可以访问的有哪些
5)Realm:可以有一个或者多个,可以认为是安全实体数据源,即用于获取安全实体的,可以是JDBC实现,也可以是内存实现等等,由用户提供。
6)SessionManager:管理Session生命周期的组件。而Shiro并不仅仅可以在Webh环境,也可以用在普通的JavaSE环境
7)CacheManager:缓存控制器,用来管理如用户、角色、权限等的缓存
8)Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密
三、谈谈一些关键的位置
这里以结合springboot与mybatis的代码为例
<!-- shiro与spring整合的依赖 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version> </dependency> <!-- ali的数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- springboot的mybatis启动器 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.version}</version> </dependency> </dependencies> <!-- fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!-- springboot的web组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
package cn.zytao.taosir.user.config; import java.util.LinkedHashMap; import java.util.Map; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Shiro的配置类 * @author taosir */ @Configuration public class ShiroConfig { /** * 创建Realm */ @Bean(name="userRealm") public UserRealm getRealm() { return new UserRealm(); } /** * 创建DefaultWebSecurityManager * @param userRealm */ @Bean(name="securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) { DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); //关联realm securityManager.setRealm(userRealm); return securityManager; } /** * 创建ShiroFilterFactoryBean */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean(); //设置安全管理器 shiroFilterFactoryBean.setSecurityManager(securityManager); //添加Shiro内置过滤器 /** * Shiro内置过滤器,可以实现权限相关的拦截器 * 常用的过滤器: * anon:无需认证(登录)可以访问 * authc:必须认证才可以访问 * user:如果使用rememberMe的功能可以直接访问 * perms:该资源必须得到资源权限才可以访问 * role:该资源必须得到角色权限才可以访问 */ Map<String, String> filterMap= new LinkedHashMap<String,String>(); //修改拦截后跳转的请求路径 shiroFilterFactoryBean.setLoginUrl("/user/badRequest"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } }
package cn.zytao.taosir.user.config; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import cn.zytao.taosir.common.model.user.User; import cn.zytao.taosir.user.mapper.UserMapper; /** * 自定义的Realm程序 * @author taosir */ public class UserRealm extends AuthorizingRealm{ @Autowired private UserMapper userMapper; /** * 执行授权逻辑 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { System.out.println("开始执行Shiro的授权方法..."); return null; } /** * 执行认证逻辑 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { System.out.println("开始执行Shiro的认证方法..."); //编写Shiro判断逻辑,判断用户名和密码 //判断用户名是否存在 UsernamePasswordToken token=(UsernamePasswordToken)arg0; User user = userMapper.findByUsername(token.getUsername()); if(user==null) return null; //判断密码是否正确 return new SimpleAuthenticationInfo("",user.getPassword(),""); } }
主要就是这两个相关类的关联,代码为我的实现,注解已经说明了相关位置写什么内容
记得配上mybatis的配置
spring: datasource: url: jdbc:mysql://localhost:3306/taosir-user?useUnicode=true&characterEncoding=utf8 username: root password: root driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource mybatis: type-aliases-package: cn.zytao.taosir.common.model.user
package cn.zytao.taosir.user.service.impl; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Service; import cn.zytao.taosir.common.exception.BadRequestException; import cn.zytao.taosir.user.service.UserService; @Service public class UserServiceImpl implements UserService{ @Override public void checkLogin(String username,String password) { /** * 使用Shiro编写认证操作 */ //获取Subject Subject subject=SecurityUtils.getSubject(); //封装用户数据 UsernamePasswordToken token=new UsernamePasswordToken(username,password); //执行登录方法 try { subject.login(token); } catch (UnknownAccountException e) { //用户名不存在 throw new BadRequestException("该用户名不存在"); } catch (IncorrectCredentialsException e) { //密码错误 throw new BadRequestException("密码不正确"); } catch (Exception e) { throw new BadRequestException("由于未知错误登录失败,请联系管理员或稍后重试"); } } }
作者:涛先森の日常
出处:https://www.cnblogs.com/it-taosir/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。