springboot整合shiro的使用
SpringBoot 整合 shiro 使用
2023-09-11 14:22:43 时间
shiro的原理已经有博客了,自己写可以问度娘
参考https://www.cnblogs.com/liyinfeng/p/8033869.html
此处直接描述实际使用
一、pom.xml引包
<!--shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version> </dependency>
二、三件套
ShiroConfig
@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shirFilter(DefaultWebSecurityManager securityManager) { System.out.println("ShiroConfiguration.shirFilter()"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //拦截器. Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); // 配置不会被拦截的链接 顺序判断 /**静态文件css及图片*/ filterChainDefinitionMap.put("/static/**", "anon"); /**webservice服务*/ filterChainDefinitionMap.put("/services/**", "anon"); filterChainDefinitionMap.put("/token/**", "anon"); filterChainDefinitionMap.put("/swagger-ui.html", "anon"); filterChainDefinitionMap.put("/webjars/**", "anon"); filterChainDefinitionMap.put("/v2/**", "anon"); filterChainDefinitionMap.put("/swagger-resources/**", "anon"); //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 filterChainDefinitionMap.put("/logout", "logout"); //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了; //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> filterChainDefinitionMap.put("/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index"); //未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public MyShiroRealm myShiroRealm(){ MyShiroRealm myShiroRealm = new MyShiroRealm(); return myShiroRealm; } @Bean public DefaultWebSecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); return securityManager; } }
MyShiroRealm
@Slf4j public class MyShiroRealm extends AuthorizingRealm { @Autowired private UserInfoService userInfoService; /***授权方法*/ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { log.info("开始授权 --> MyShiroRealm.doGetAuthorizationInfo()"); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); UserInfo userInfo = (UserInfo)principal.getPrimaryPrincipal(); for(SysRole role:userInfo.getRoleList()){ authorizationInfo.addRole(role.getRole()); for(SysPermission p:role.getPermissions()){ authorizationInfo.addStringPermission(p.getPermission()); } } log.info("结束成功!"); return authorizationInfo; } /**认证方法*/ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { log.info("开始认证 --> MyShiroRealm.doGetAuthenticationInfo()"); //获取用户的输入的账号. String username = (String)token.getPrincipal(); System.out.println(token.getCredentials()); //通过username从数据库中查找 User对象,如果找到,没找到. //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法 log.info("认证 --> 通过账户查询入参"+username); UserInfo userInfo = userInfoService.findByUsername(username); log.info("认证 --> 通过账户查询出参"+ JSON.toJSONString(userInfo)); if(userInfo == null){ log.info("认证失败!"); return null; } SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( userInfo, //用户名 userInfo.getPassword(), //密码 ByteSource.Util.bytes(userInfo.getSalt()),//salt=username+salt getName() //realm name ); log.info("认证成功!"); return authenticationInfo; } }
给shiro添加token,这时token中的用户才会执行认证授权的流程
@ApiOperation("登陆获取token") @PostMapping("/login") @LoginToken public Object login(@RequestParam("username") String username, @RequestParam("password") String password) { JSONObject jsonObject = new JSONObject(); UserInfo userInfo = userInfoService.findByUsername(username); if (userInfo == null) { jsonObject.put("message", "登录失败,用户不存在"); return jsonObject; } else { EncryptUtil encryptUtil = EncryptUtil.getInstance(); String passcode = encryptUtil.MD5(encryptUtil.Base64Encode(password) + userInfo.getSalt()); //校验登陆密码加盐的一致性 if (!userInfo.getPassword().equals(passcode)) { jsonObject.put("message", "登录失败,密码错误"); return jsonObject; } else { //shiro的token //添加用户认证信息 Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken shiroToken = new UsernamePasswordToken(userInfo.getUsername(),userInfo.getPassword()); //进行验证,这里可以捕获异常,然后返回对应信息 subject.login(shiroToken); SignInReq sign = new SignInReq(); sign.setId(Integer.toString(userInfo.getUid())); sign.setUserName(userInfo.getUsername()); //此处的密码是加盐加密过后的 sign.setPassword(userInfo.getPassword()); long now = System.currentTimeMillis(); String dateStr = DateUtil.parseDateToStr(new Date(now+expireTime), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS); String token = JwtTokenUtil.createJWT(expireTime, sign); jsonObject.put("token", token); jsonObject.put("expireTime",dateStr); jsonObject.put("sign", sign); return jsonObject; } } }
当然权限crud的自己来一套
最后就可以用了,哈哈
相关文章
- springboot+shiro+redis(单机redis版)整合教程-续(添加动态角色权限控制)
- 补习系列(14)-springboot redis 整合-数据读写
- SpringBoot入门之简单配置
- springboot整合shiro
- boke练习: springboot整合springSecurity出现的问题,post,delete,put无法使用
- SpringBoot整合MyBatis
- Jenkins:用maven在本地打包部署一个github的springboot项目(Jenkins 2.257)
- IDEA整合SpringBoot-Vue项目
- 【项目实战】Springboot整合SCP,实现远程文件拷贝与传输功能
- 【最全详细配置】SpringBoot整合Redis
- 【SpringBoot19】SpringBoot中整合Ehcache实现热点数据缓存
- 【【SpringBoot系列】最详细demo--自定义日志脱敏组件,简单3 步完成 Spring Boot 的日志脱敏
- 实践丨SpringBoot整合Mybatis-Plus项目存在Mapper时报错
- springboot整合minio最新版
- SpringBoot缓存技术整合Ehcache
- SpringBoot整合Servlet、Filter、Listener、访问静态资源、文件上传
- springboot整合zookeeper实现分布式锁
- Redis---整合SpringBoot篇
- Springboot项目如何设计接口中敏感字段的加密、解密?
- SpringBoot中使用Easyexcel实现Excel导入导出功能(一)
- springboot注解