Spring Boot 整合Shiro 最新 最全面(Mybatis版本)

网友投稿 732 2022-10-07

Spring Boot 整合Shiro 最新 最全面(Mybatis版本)

Spring Boot 整合Shiro 最新 最全面(Mybatis版本)

1: 依赖

org.springframework.boot spring-boot-starter-thymeleaf com.github.theborakompanioni thymeleaf-extras-shiro ${thymeleaf-shiro.version} org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.2 mysql mysql-connector-java org.apache.shiro shiro-spring 1.5.1 org.springframework.boot spring-boot-devtools runtime true org.springframework.boot spring-boot-configuration-processor true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.xmlunit xmlunit-core

2: application.xml配置

#server.servlet.context-path=/hello##端口号server.port=8888##检查 mybatis 配置是否存在,一般命名为 mybatis-config.xmlmybatis.check-config-location =true##配置文件位置 Resource下mybaits文件夹mybatis.config-location=classpath:mybatis/mybatis-config.xml## mapper xml 文件地址 Resource下mapper文件夹mybatis.mapper-locations=classpath*:mapper/*Mapper.xml##日志级别 com.yang.dao 为包名#logging.level.com.dgw.springbootandshiro.dao=debug##数据库urlspring.datasource.url=jdbc:mysql://localhost/rbac?userSSL=true&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT##数据库用户名spring.datasource.username=root##数据库密码spring.datasource.password=root##数据库驱动spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.thymeleaf.check-template-location=truespring.thymeleaf.encoding=UTF-8spring.thymeleaf.prefix=classpath:/templates/spring.thymeleaf.suffix=.html# 建议在开发时关闭缓存,不然没法看到实时页面spring.thymeleaf.cache=false##去除thymeleaf的html严格校验spring.thymeleaf.mode=HTMLspring.main.allow-bean-definition-overriding=true#debug=true#简单设置一下日志等级logging.level.web=infologging.level.root=info

3: Mybatis 配置:

目录结构如下:

Mybatis 配置文件

实体类

@Data@AllArgsConstructor@NoArgsConstructorpublic class User { private Integer id; private String username; private String password; private String salt;}@Data@AllArgsConstructor@NoArgsConstructorpublic class Role { private Integer id; private String roleName; private Date createTime;}@Data@AllArgsConstructor@NoArgsConstructorpublic class Permission { private Integer id; private String permissionName; private Date createTime;}

dao接口: 部分 其余扎着框框画鸭蛋

@Mapperpublic interface UserMapper { User queryUserByUsername(@Param("username") String username); Integer insertUser(User user);}

services实现:

@Servicepublic class UserServiceImpl implements UserService { @Autowired private UserMapper userDAO; @Override @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = SQLException.class) public User queryUserByUsername(String username) { return userDAO.queryUserByUsername(username); } @Override public Integer insertUser(User user) { // 加密 String salt = UUID.randomUUID().toString(); String s = new Sha256Hash(user.getPassword(), salt, MyConstant.INTERCOUNT).toBase64(); // 设置密文 user.setPassword(s); // 设置盐 user.setSalt(salt); return userDAO.insertUser(user); }}

3: Shiro配置

Realm配置i

public class ShiroRealm extends AuthorizingRealm { @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired private PermissionService permissionService; // 授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { String username = (String)principalCollection.getPrimaryPrincipal(); // 查询当前用户的权限信息 Set roles = roleService.queryAllRolenameByUsername(username); Set perms = permissionService.queryAllPermissionByUsername(username); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roles); simpleAuthorizationInfo.setStringPermissions(perms); return simpleAuthorizationInfo; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String usernmae = (String) authenticationToken.getPrincipal(); User user = userService.queryUserByUsername(usernmae); if (user == null) { return null; } //这里会去校验密码是否正确 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName() ); return authenticationInfo; }}

Shiroconfig 配置

@Configurationpublic class ShiroConfig { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Bean("shiroFilterFactoryBean") public ShiroFilterFactoryBean shirFilter(@Qualifier("securityManager") SecurityManager securityManager) { logger.info("启动shiroFilter--时间是:" + new Date()); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //shiro- Map filterChainDefinitionMap = new LinkedHashMap(); // // Map filterMap=new LinkedHashMap(); filterMap.put("MyRememberFilter", new MyRememberFilter()); shiroFilterFactoryBean.setFilters(filterMap); // 如果不设置默认会自动寻找Web工程根目录下的"/login"页面,即本文使用的login.html shiroFilterFactoryBean.setLoginUrl("/login"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/main"); //错误页面,认证不通过跳转 shiroFilterFactoryBean.setUnauthorizedUrl("/error"); //未授权界面 shiroFilterFactoryBean.setUnauthorizedUrl("/403"); // 配置不被拦截的资源及链接 filterChainDefinitionMap.put("/static/**", "anon"); // 退出过滤器 filterChainDefinitionMap.put("/logout", "logout"); //开启注册页面不需要权限 filterChainDefinitionMap.put("/user/login", "anon"); filterChainDefinitionMap.put("/user/register", "anon"); //配置需要认证权限的 filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } /** * 配置shiro的生命周期 * * @return */ @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * 定义加密规则 存入密码时也必须加密 */ @Bean public HashedCredentialsMatcher myMatcher(){ HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); matcher.setHashAlgorithmName("SHA-256"); // true means hex encoded, false means base64 encoded matcher.setStoredCredentialsHexEncoded(false); matcher.setHashIterations(10000); return matcher; } public class MyRememberFilter extends FormAuthenticationFilter { protected boolean isAccessAllowed(HttpServletRequest request, HttpServletResponse response, Object mappedValue){ Subject subject=getSubject(request,response); if(!subject.isAuthenticated() && subject.isRemembered()){ if(subject.getSession().getAttribute("user")==null &&subject.getPrincipal()!=null){ subject.getSession().setAttribute("user",subject.getPrincipal()); } } return subject.isAuthenticated() || subject.isRemembered(); } } /* private class MyMatcher extends HashedCredentialsMatcher { @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; String pwd = encrypt(String.valueOf(usernamePasswordToken.getPassword())); String mysqlpwd = (String) info.getCredentials(); logger.info("密码"+mysqlpwd); logger.info("密码"+pwd); return this.equals(pwd, mysqlpwd); } //将传进来的密码进行加密的方法 private String encrypt(String data) { // 加密 String salt = UUID.randomUUID().toString(); String s = new Sha256Hash(data, salt, MyConstant.INTERCOUNT).toBase64(); return s; } }*/ /** * 自定义身份认证Realm(包含用户名密码校验,权限校验等) */ @Bean public ShiroRealm myShiroRealm() { ShiroRealm myShiroRealm = new ShiroRealm(); myShiroRealm.setCredentialsMatcher(myMatcher()); return myShiroRealm; } /** * 使用shiro 支持thymeleaf 模版引擎 */ @Bean public ShiroDialect shiroDialect() { return new ShiroDialect(); } /** * 配置记住我Cookie对象参数,rememberMeCookie()方法是设置Cookie的生成模版 */ public SimpleCookie rememberMeCookie() { //这个参数是cookie的名称,对应前端的checkbox的name=rememberMe SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); //cookie生效时间为10秒 simpleCookie.setMaxAge(100000); return simpleCookie; } /** * 配置Cookie管理对象,rememberMeManager()方法是生成rememberMe管理器 */ @Bean public CookieRememberMeManager rememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie()); return cookieRememberMeManager; } /** * 配置sessionCookie对象参数,sessionCookie()方法是设置Cookie的生成模版 */ public SimpleCookie sessionIdCookie() { //这个参数是cookie的名称,对应前端的checkbox的name=rememberMe SimpleCookie simpleCookie = new SimpleCookie("JSESSIONID"); //只允许 simpleCookie.setHttpOnly(true); //cookie生效时间为10秒 默认为-1 simpleCookie.setMaxAge(-1); return simpleCookie; } /** * 配置Cookie管理对象,rememberMeManager()方法是生成rememberMe管理器 */ @Bean public DefaultWebSessionManager sessionManager() { DefaultWebSessionManager webSessionManager = new DefaultWebSessionManager(); webSessionManager.setSessionIdCookie(sessionIdCookie()); // session全局超时时间, 单位:毫秒 ,30分钟 默认值为1800000 webSessionManager.setGlobalSessionTimeout(1800000); //开启检测器,默认开启 webSessionManager.setSessionIdUrlRewritingEnabled(true); // 检测间隔事件 时间为1小时 webSessionManager.setSessionValidationInterval(3600000); // 设置- //webSessionManager.setSessionListeners(); return webSessionManager; } @Bean public CacheManager cacheManager() { return new MemoryConstrainedCacheManager(); } @Bean(name = "securityManager") public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //注入自定义myRealm securityManager.setRealm(myShiroRealm()); //注入自定义cacheManager securityManager.setCacheManager(cacheManager()); //注入记住我管理器 securityManager.setRememberMeManager(rememberMeManager()); //注入自定义sessionManager securityManager.setSessionManager(sessionManager()); return securityManager; } //开启shiro aop注解支持,不开启的话权限验证就会失效 @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor sourceAdvisor = new AuthorizationAttributeSourceAdvisor(); sourceAdvisor.setSecurityManager(securityManager); return sourceAdvisor; } //配置异常处理,不配置的话没有权限后台报错,前台不会跳转到403页面 @Bean(name = "simpleMappingExceptionResolver") public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() { SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理 mappings.setProperty("UnauthorizedException", "403"); simpleMappingExceptionResolver.setExceptionMappings(mappings); // None by default simpleMappingExceptionResolver.setDefaultErrorView("403"); // No default simpleMappingExceptionResolver.setExceptionAttribute("ex"); // Default is "exception" return simpleMappingExceptionResolver; }}

4: thymeleaf

login.html

Insert title here


5 controller

@Controller@RequestMapping("/user")public class LoginController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private UserService userService; @GetMapping("/login") public String login() { return "login"; } @PostMapping("/login") public String loginLogic(User user) { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword()); // 登录失败会抛出异常,则交由异常解析器处理 token.setRememberMe(true); subject.login(token); return "main"; } @GetMapping("/register") public String regiter() { return "register"; } @PostMapping("/register") public String logicRegiter(User user) { userService.insertUser(user); return "redirect:login"; }}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:本地搭建微信小程序服务器的实现方法(本地搭建微信小程序服务器的实现方法是)
下一篇:关于微信小程序登录鉴权的步骤(小程序登录验证授权过程)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~