SpringBoot 整合shiro框架

SpringBoot 整合shiro框架网上有很多整合 shiro 的博客分享 但是貌似没找到一个完整 并且能够实现的 不是包的问题 就是代码的问题 也可能是自己的问题 或者版本的问题 所以 整理了一版自己已应用的 maven 依赖 lt parent gt lt groupId gt org springframew boot lt groupId gt lt artifactId gt sprin

网上有很多整合shiro的博客分享,但是貌似没找到一个完整,并且能够实现的。不是包的问题,就是代码的问题,也可能是自己的问题,或者版本的问题。所以,整理了一版自己已应用的.

maven依赖:

 
   
   
     org.springframework.boot 
    
   
     spring-boot-starter-parent 
    
   
     2.0.2.RELEASE 
    
    
   
   
    
     
     
       org.springframework.cloud 
      
     
       spring-cloud-dependencies 
      
     
       Finchley.RELEASE 
      
     
       pom 
      
     
       import 
      
     
    
   
   
    
    
      org.springframework.cloud 
     
    
      spring-cloud-starter-config 
     
    
    
    
      org.mybatis.spring.boot 
     
    
      mybatis-spring-boot-starter 
     
    
      1.3.2 
     
    
    
    
      org.springframework.boot 
     
    
      spring-boot-starter-data-jpa 
     
    
    
    
      org.springframework.boot 
     
    
      spring-boot-starter-web 
     
    
    
    
      net.sourceforge.nekohtml 
     
    
      nekohtml 
     
    
      1.9.22 
     
    
    
    
    
    
      org.apache.shiro 
     
    
      shiro-spring 
     
    
      1.4.0 
     
    
    
    
    
      mysql 
     
    
      mysql-connector-java 
     
    
      5.1.35 
     
    
    
    
      com.alibaba 
     
    
      druid 
     
    
      1.0.11 
     
    
    
    
      org.projectlombok 
     
    
      lombok 
     
    
      true 
     
    
    
    
      com.alibaba 
     
    
      fastjson 
     
    
      1.2.47 
     
    
    
    
      commons-io 
     
    
      commons-io 
     
    
      2.4 
     
    
    
    
      org.apache.tomcat.embed 
     
    
      tomcat-embed-jasper 
     
    
      provided 
     
    
    
    
      javax.servlet 
     
    
      javax.servlet-api 
     
    
      provided 
     
    
    
    
      javax.servlet 
     
    
      jstl 
     
    
   

MyShiroRealm.java(权限配置)

import com.simple.users.dto.entity.UserInfo; import com.simple.users.service.UserInfoService; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.crypto.hash.Md5Hash; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import javax.annotation.Resource; import java.util.HashSet; import java.util.Set; public class MyShiroRealm extends AuthorizingRealm { @Resource private UserInfoService userInfoService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); UserInfo userInfo = (UserInfo) principals.getPrimaryPrincipal(); /* * for (SysRole role : userInfo.getRoleList()) { * authorizationInfo.addRole(role.getRole()); for (SysPermission p : * role.getPermissions()) { * authorizationInfo.addStringPermission(p.getPermission()); } } */ // 获取用户角色 Set 
  
    roleSet = new HashSet 
   
     (); roleSet.add(""); info.setRoles(roleSet); // 获取用户权限 Set 
    
      permissionSet = new HashSet 
     
       (); permissionSet.add("权限添加"); permissionSet.add("权限删除"); info.setStringPermissions(permissionSet); return info; } / * 主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。 * * @param authcToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; String username = token.getUsername(); UserInfo userInfo = userInfoService.findByUsername(username); if (userInfo == null) { return null; } String password = new String((char[]) token.getCredentials()); String pwdMd5 = (new Md5Hash(password, username)).toHex(); System.out.println("----->>pwdMd5====" + pwdMd5); UserInfo user = new UserInfo(); user.setUsername(username); user.setPassword(pwdMd5); return new SimpleAuthenticationInfo(user, pwdMd5, ByteSource.Util.bytes(username), getName()); } } 
      
     
    
  

ShiroConfig.java(shiro配置)

import com.simple.utils.Base64Util; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.CookieRememberMeManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.SimpleCookie; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; @Configuration public class ShiroConfig { / * ShiroDialect,为了在thymeleaf里使用shiro的标签的bean * 开启thymeleaf模板访问,注释则使用配置的jsp或者HTML访问模式 * @return */ // @Bean // public ShiroDialect shiroDialect() { // return new ShiroDialect(); // } @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { System.out.println("--------ShiroConfiguration.shirFilter()"); // 添加安全管理器 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); // 如果不设置默认会自动寻找Web工程根目录下的"/index.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/"); // 登录成功后要跳转的链接 // shiroFilterFactoryBean.setSuccessUrl("/?path=user/main"); // 添加shiro内置过滤器 / * anon:表示可以匿名使用。 authc:表示需要认证(登录)才能使用,没有参数 * * roles:参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时, * 例如admins/user/=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。 * * perms:参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割, * 例如/admins/user/=perms["user:add:*,user:modify:*"], * 当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。 * * rest:根据请求的方法,相当于/admins/user/=perms[user:method] * ,其中method为post,get,delete等。 * * port:当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString, * 其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口, * queryString是你访问的url里的?后面的参数。 authcBasic:没有参数表示httpBasic认证 * * ssl:表示安全的url请求,协议为https user:当登入操作时不做检查 */ Map 
  
    filterChainDefinitionMap = new LinkedHashMap 
   
     (); // 静态资源的处理 filterChainDefinitionMap.put("/js/", "anon"); filterChainDefinitionMap.put("/css/", "anon"); filterChainDefinitionMap.put("/img/", "anon"); filterChainDefinitionMap.put("/fonts/", "anon"); filterChainDefinitionMap.put("/plugins/", "anon"); // // 请求路径的处理 filterChainDefinitionMap.put("/H-PLE/", "authc"); // 退出系统的过滤器 filterChainDefinitionMap.put("/userInfo/logout", "logout"); filterChainDefinitionMap.put("/userInfo/login", "anon"); // 默认所有资源必须认证才能访问 filterChainDefinitionMap.put("/", "authc"); // 未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } / * 凭证匹配器 (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了 ) * * @return */ @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:这里使用MD5算法; hashedCredentialsMatcher.setHashIterations(1);// 散列的次数(默认一次),比如散列两次,相当于 md5(md5("")); return hashedCredentialsMatcher; } @Bean public MyShiroRealm myShiroRealm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; } @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); // 注入记住我管理器; securityManager.setRememberMeManager(rememberMeManager()); return securityManager; } / * cookie对象; * * @return */ public SimpleCookie rememberMeCookie() { // 这个参数是cookie的名称,对应前端的checkbox的name = rememberMe SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); // 
     simpleCookie.setMaxAge(); return simpleCookie; } / * cookie管理对象;记住我功能 * * @return */ public CookieRememberMeManager rememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie()); // rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位) try { cookieRememberMeManager.setCipherKey(Base64Util.decode("3AvVhmFLUs0KTA3Kprsdag==")); } catch (Exception e) { e.printStackTrace(); } return cookieRememberMeManager; } / * 开启shiro aop注解支持. 使用代理方式;所以需要开启代码支持; * * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } @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); // None by default r.setDefaultErrorView("error"); // No default r.setExceptionAttribute("ex"); // Default is "exception" // r.setWarnLogCategory("example.MvcLogger"); // No default return r; } } 
    
  

UserController.java(登录应用)

@ResponseBody @RequestMapping(value = "/login", method = RequestMethod.POST, produces = { "application/json; charset=UTF-8" }) public Object login(@RequestBody JSONObject jsonP) { JSONObject result = new JSONObject(); JSONObject resultHd = new JSONObject(); JSONObject resultBd = new JSONObject(); String userName = Null.nullToSpace(jsonP.getString("userName")); String passWord = Null.nullToSpace(jsonP.getString("passWord")); Boolean rememberMe = jsonP.getBoolean("agree"); System.out.println("userName--" + userName + "; passWord--" + passWord + "; rememberMe--" + rememberMe); UsernamePasswordToken token = new UsernamePasswordToken(userName, passWord, rememberMe); try { SecurityUtils.getSubject().login(token); resultHd.put("error", "成功"); resultHd.put("errorCode", "0"); resultHd.put("data", new HashMap()); } catch (UnknownAccountException e) { resultHd.put("error", "失败"); resultHd.put("errorCode", "2"); resultHd.put("data", new HashMap()); e.printStackTrace(); } catch (IncorrectCredentialsException e) { resultHd.put("error", "失败"); resultHd.put("errorCode", "3"); resultHd.put("data", new HashMap()); e.printStackTrace(); } catch (AuthenticationException e) { // 其他错误,比如锁定,如果想单独处理请单独catch处理 resultHd.put("error", "失败"); resultHd.put("errorCode", "1"); resultHd.put("data", new HashMap()); e.printStackTrace(); } result.put("header", resultHd); result.put("body", resultBd); return result; } 

User实体:

权限类:SysPermission.java import lombok.Getter; import lombok.Setter; import lombok.ToString; import javax.persistence.*; import java.io.Serializable; import java.util.List; @Getter @Setter @ToString @Entity public class SysPermission implements Serializable { @Id @GeneratedValue private Integer id;// 主键. private String name;// 名称. @Column(columnDefinition = "enum('menu','button')") private String resourceType;// 资源类型,[menu|button] private String url;// 资源路径. private String permission; // 权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view private Long parentId; // 父编号 private String parentIds; // 父编号列表 private Boolean available = Boolean.FALSE; @ManyToMany @JoinTable(name = "SysRolePermission", joinColumns = { @JoinColumn(name = "permissionId") }, inverseJoinColumns = { @JoinColumn(name = "roleId") }) private List 
  
    roles; } ---------------------------------------------------------------------------------------- 角色类:SysRole.java import lombok.Getter; import lombok.Setter; import lombok.ToString; import javax.persistence.*; import java.util.List; @Getter @Setter @ToString @Entity public class SysRole { @Id @GeneratedValue private Integer id; // 编号 private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的: private String description; // 角色描述,UI界面显示使用 private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不会添加给用户 // 角色 -- 权限关系:多对多关系; @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "SysRolePermission", joinColumns = { @JoinColumn(name = "roleId") }, inverseJoinColumns = { @JoinColumn(name = "permissionId") }) private List 
   
     permissions; // 用户 - 角色关系定义; @ManyToMany @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "roleId") }, inverseJoinColumns = { @JoinColumn(name = "uid") }) private List 
    
      userInfos;// 一个角色对应多个用户 // 省略 get set 方法 } ---------------------------------------------------------------------------------------- 用户类:UserInfo.java import lombok.Getter; import lombok.Setter; import lombok.ToString; import javax.persistence.*; import java.io.Serializable; import java.util.List; @Getter @Setter @ToString @Entity public class UserInfo implements Serializable { @Id @GeneratedValue private Integer uid; @Column(unique = true) private String username;// 帐号 private String name;// 名称(昵称或者真实姓名,不同系统不同定义) private String password; // 密码; private String salt;// 加密密码的盐 private byte state;// 用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定. @ManyToMany(fetch = FetchType.EAGER) // 立即从数据库中进行加载数据; @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns = { @JoinColumn(name = "roleId") }) private List 
     
       roleList;// 一个用户具有多个角色 / * 密码盐. * * @return */ public String getCredentialsSalt() { return this.username + this.salt; } // 重新对盐重新进行了定义,用户名+salt,这样就更加不容易被激活成功教程 } 
      
     
    
  

数据:

用户表:账号admin 密码admin INSERT INTO `user_info`(`uid`, `name`, `password`, `salt`, `state`, `username`) VALUES (1, '管理员', 'f6fdffe48c908deb0f4c3bd36c032e72', '87', 0, 'admin'); 权限表: INSERT INTO `sys_permission`(`id`, `available`, `name`, `parent_id`, `parent_ids`, `permission`, `resource_type`, `url`) VALUES (1, b'0', '用户管理', 0, '0/', 'userInfo:view', 'menu', 'userInfo/userList'); INSERT INTO `sys_permission`(`id`, `available`, `name`, `parent_id`, `parent_ids`, `permission`, `resource_type`, `url`) VALUES (2, b'0', '用户添加', 1, '0/1', 'userInfo:add', 'button', 'userInfo/userAdd'); INSERT INTO `sys_permission`(`id`, `available`, `name`, `parent_id`, `parent_ids`, `permission`, `resource_type`, `url`) VALUES (3, b'0', '用户删除', 1, '0/1', 'userInfo:del', 'button', 'userInfo/userDel'); 角色表: INSERT INTO `sys_role`(`id`, `available`, `description`, `role`) VALUES (1, b'0', '管理员', 'admin'); INSERT INTO `sys_role`(`id`, `available`, `description`, `role`) VALUES (2, b'0', 'VIP会员', 'vip'); 

里面的Null类引用,可以在 https://blog.csdn.net/weixin_/article/details/ (Java 一些常用工具类)这里面找工具类。

目录结构

yml配置:

druid: stat: mergeSql: true; slowSqlMillis: 5000 logging: level: com: DEBUG mybatis: mapper-locations: classpath:com/simple/*/dto/maps/*Mapper.xml type-aliases-package: com.simple.* server: port: 8081 servlet: context-path: / spring: datasource: driverClassName: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://127.0.0.1:3306/oa?characterEncoding=utf8&autoReconnect=true&useSSL=false&useAffectedRows=true username: root password: root filters: stat,wall,log4j initialSize: 5 maxActive: 20 maxPoolPreparedStatementPerConnectionSize: 20 maxWait: 60000 minEvictableIdleTimeMillis:  minIdle: 5 poolPreparedStatements: true testOnBorrow: false testOnReturn: false testWhileIdle: true timeBetweenEvictionRunsMillis: 60000 validationQuery: SELECT 1 FROM DUAL http: encoding: charset: UTF-8 enabled: true jpa: show-sql: true hibernate: ddl-auto: update naming: physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy properties: hibernate: dialect: org.hibernate.dialect.MySQL5Dialect mvc: locale: zh_CN view: prefix: /WEB-INF/jsp/ suffix: .jsp static-path-pattern: / #资源名称md5方式 resources: chain: strategy: content: enabled: true paths: / 

以上就是shiro完整代码,如有疑问,随时评论.

转载请注明出处!

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/204228.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午8:42
下一篇 2026年3月19日 下午8:42


相关推荐

  • 《从点子到产品》读书笔记之产品价值和用户痛点

    最近从朋友那里阅读了《从点子到产品:产品经理的价值观与方法论》这本书,作者刘飞,感觉还不错,至少对想转行或刚转性做产品经理而又缺乏经验的朋友有很大的借鉴作用,决定将其思想进行总结。(绝非书托,哈哈哈)

    2021年12月29日
    58
  • Netty之ByteBuf

    Netty之ByteBuf一、功能原理ByteBuf是一个byte存放的缓冲区。ByteBuf通过两个位置的指针来协助缓冲区的读写操作,读操作使用readIndex,写操作使用writeIndex。+——————-+——————+——————+|discardablebytes|readablebytes

    2026年1月25日
    7
  • kimi中文讲解

    kimi中文讲解

    2026年3月12日
    1
  • 忘记阿里云管理终端密码怎么办

    忘记阿里云管理终端密码怎么办

    2021年9月23日
    54
  • WinSCP连接被拒绝「建议收藏」

    WinSCP连接被拒绝「建议收藏」之前用WinSCP连接华为云服务器传输文件的时候没有出现过问题,但是现在连接实验室电脑的时候报“网络错误,连接被拒绝”。上网查了一下,发现是实验室服务器没有安装openssh-server,参考博文进行安装:Ubuntu安装sshd服务_我是大魔王2的博客-CSDN博客_ubuntu安装sshd具体安装步骤:1.安装openssh-serversudoapt-getinstallopenssh-server2.检查sshd是否启动一般安装成功后就会启动sshd服务,可以通过.

    2025年12月15日
    4
  • 【matlab】meshgrid的使用

    【matlab】meshgrid的使用函数参数列表[X,Y]=meshgrid(x,y)[X,Y]=meshgrid(x)[X,Y,Z]=meshgrid(x,y,z)[X,Y,Z]=meshgrid(x)meshgrid可以生成2D或者3D的矩阵,如果为2D,矩阵的shape为(y.length,x.length)如果为3D,矩阵的shape为(y.length,x.length,z.length)代码示例sample1x=1:2;%length2y=3:5;%length3[X,Y]=m

    2022年5月29日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号