springboot整合shiro&shiro自定义过滤器 您所在的位置:网站首页 办理护照要怎么办理 springboot整合shiro&shiro自定义过滤器

springboot整合shiro&shiro自定义过滤器

#springboot整合shiro&shiro自定义过滤器| 来源: 网络整理| 查看: 265

  关于shiro的简介与使用方法在shiro分类中已经使用过了,而且在spring中已经成功的整合了shiro。下面研究springboot+thymeleaf中使用shiro。

  spring整合shiro参考:https://www.cnblogs.com/qlqwjy/p/7257502.html

  springboot整合shiro实际上是将xml整合的方式转为Java配置方式。

 

  基于SpringDataJPA。

1.springboot整合shiro 1.系统权限需要的五张表(三个bean,SpringdataJPA自动创建中间表) package cn.qlq.shiro.bean; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "system_shiro_permission") public class Permission { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String name; // 权限名 唯一 private String url; // 访问地址信息 唯一 private String description; // 描述信息   // get,setter }

 

 

package cn.qlq.shiro.bean; import java.util.List; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name = "system_shiro_role") public class Role { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String name; // 角色名 唯一 private String description; // 描述信息 @OneToMany(fetch = FetchType.EAGER) private List permissions; // 一个用户角色对应多个权限 // getter,setter }

 

 

package cn.qlq.shiro.bean; import java.util.List; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name = "system_shiro_user") public class ShiroUser { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String username;// 用户名 唯一 private String password;// 用户密码 @OneToMany(fetch = FetchType.EAGER) private List roles;// 用户角色 一个用户可能有一个角色,也可能有 多个角色 // getter,setter }

 

2. pom文件增加如下配置: org.apache.shiro shiro-spring 1.3.2

 

 

3.mapper层采用SpringDataJPA自动创建的接口实现 package cn.qlq.shiro.mapper; import org.springframework.data.jpa.repository.JpaRepository; import cn.qlq.shiro.bean.Permission; public interface PermissionMapper extends JpaRepository { Permission findByName(String name); }

 

 

package cn.qlq.shiro.mapper; import org.springframework.data.jpa.repository.JpaRepository; import cn.qlq.shiro.bean.Role; public interface RoleMapper extends JpaRepository { Role findByName(String name); }

 

 

package cn.qlq.shiro.mapper; import org.springframework.data.jpa.repository.JpaRepository; import cn.qlq.shiro.bean.ShiroUser; public interface ShiroUserMapper extends JpaRepository { ShiroUser findByUsername(String username); ShiroUser findByUsernameAndPassword(String username, String password); }

 

4.自定义Realm和Shiro配置 package cn.qlq.shiro; import javax.annotation.PostConstruct; import org.apache.shiro.SecurityUtils; 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.credential.HashedCredentialsMatcher; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import cn.qlq.shiro.bean.Permission; import cn.qlq.shiro.bean.Role; import cn.qlq.shiro.bean.ShiroUser; import cn.qlq.shiro.mapper.ShiroUserMapper; @Component public class UserAuthRealm extends AuthorizingRealm { @Autowired private ShiroUserMapper shiroUserMapper; /** * 权限核心配置 根据数据库中的该用户 角色 和 权限 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); ShiroUser user = (ShiroUser) principals.getPrimaryPrincipal(); for (Role role : user.getRoles()) { // 获取 角色 authorizationInfo.addRole(role.getName()); // 添加 角色 for (Permission permission : role.getPermissions()) { // 获取 权限 authorizationInfo.addStringPermission(permission.getName());// 添加 // 权限 } } return authorizationInfo; } /** * 用户登陆凭证信息 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); ShiroUser user = shiroUserMapper.findByUsername(username); if (user == null) { return null; } AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName()); return authenticationInfo; } // 清除缓存 public void clearCache() { PrincipalCollection principalCollection = SecurityUtils.getSubject().getPrincipals(); super.clearCache(principalCollection); } }

 

 

package cn.qlq.shiro; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; 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.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import cn.qlq.shiro.bean.Permission; import cn.qlq.shiro.mapper.PermissionMapper; @Configuration public class ShiroConfig { @Autowired private PermissionMapper permissionMapper; @Autowired private UserAuthRealm userAuthRealm; /** * 配置 资源访问策略 . web应用程序 shiro核心过滤器配置 */ @Bean public ShiroFilterFactoryBean factoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager); factoryBean.setLoginUrl("/shiro/login.html");// 登录页 // 首页(这个不需要设置,因为是JS登录之后自己重定向) // factoryBean.setSuccessUrl("/shiro/index.html"); factoryBean.setUnauthorizedUrl("/shiro/unauthorized.html");// 未授权界面; // 自定义filter配置( 配置 拦截过滤器链) factoryBean.setFilterChainDefinitionMap(setFilterChainDefinitionMap()); return factoryBean; } /** * 配置 SecurityManager,可配置一个或多个realm */ @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userAuthRealm); // securityManager.setRealm(xxxxRealm); return securityManager; } /** * 开启shiro 注解支持. 使以下注解能够生效 : 需要认证 * {@link org.apache.shiro.authz.annotation.RequiresAuthentication * RequiresAuthentication} 需要用户 * {@link org.apache.shiro.authz.annotation.RequiresUser RequiresUser} 需要访客 * {@link org.apache.shiro.authz.annotation.RequiresGuest RequiresGuest} * 需要角色 {@link org.apache.shiro.authz.annotation.RequiresRoles * RequiresRoles} 需要权限 * {@link org.apache.shiro.authz.annotation.RequiresPermissions * RequiresPermissions} */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } /** * 配置 拦截过滤器链. map的键 : 资源地址 ; map的值 : 所有默认Shiro过滤器实例名 默认Shiro过滤器实例 参考 : * {@link org.apache.shiro.web.filter.mgt.DefaultFilter} */ private Map setFilterChainDefinitionMap() { Map filterMap = new LinkedHashMap(); // 注册 数据库中所有的权限 及其对应url List allPermission = permissionMapper.findAll();// 数据库中查询所有权限 for (Permission p : allPermission) { filterMap.put(p.getUrl(), "perms[" + p.getName() + "]"); // 拦截器中注册所有的权限 } filterMap.put("/static/**", "anon"); // 公开访问的资源 filterMap.put("/shiro/doLogin.html", "anon"); // 登录地址放开 filterMap.put("/logout", "logout"); // 配置登出页,shiro已经帮我们实现了跳转 filterMap.put("/**", "authc"); // 所有资源都需要经过验证 return filterMap; } }

 

 

5.控制层代码和登录代码 package cn.qlq.shiro.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("shiro") public class ShiroIndexController { @RequestMapping("login") public String login() { return "shiro/login"; } @RequestMapping("index") public String index() { return "shiro/index"; } @RequestMapping("unauthorized") public String unauthorized() { return "shiro/unauthorized"; } }

 

 

package cn.qlq.shiro.controller; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import cn.qlq.shiro.bean.ShiroUser; import cn.qlq.shiro.mapper.ShiroUserMapper; import cn.qlq.utils.JSONResultUtil; @Controller @RequestMapping("shiro") public class ShiroLoginController { @Autowired private ShiroUserMapper shiroUserMapper; @RequestMapping("doLogin") @ResponseBody public JSONResultUtil doLogin(String username, String password, HttpServletRequest request) { ShiroUser user = shiroUserMapper.findByUsernameAndPassword(username, password); if (user == null) { return new JSONResultUtil(false, "账号或者密码错误"); } // shiro中进行登录 Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); currentUser.login(token); // 设置登录的user HttpSession session = request.getSession(); session.setAttribute("user", user); return new JSONResultUtil(true, "ok"); } }

 

6. 前台登录界面和首页(thymeleaf界面+layui框架) doctype html> 后台登录-X-admin2.0 x-admin2.0-管理登录(Shiro)

 

登录JS代码login.js

$(function() { layui.use('form', function(){ var form = layui.form; // layer.msg('玩命卖萌中', function(){ // //关闭后的操作 // }); //监听提交 form.on('submit(login)', function(data){ //打印一下填写的值然后区后台进行登陆 $.post("/shiro/doLogin.html",data.field,function(result){ if(result!=null && result.success == true){ window.location = "/shiro/index.html"; }else{ layer.msg(result.msg); } },'json'); return false; }); }); })

 

首页index.html代码:

doctype html> 后台登录-X-admin2.0 首页

 

2.thymeleaf整合Shiro标签 1.pom文件引入 com.github.theborakompanioni thymeleaf-extras-shiro 1.2.1

 

2.ShiroConfig里增加如下bean @Bean public ShiroDialect shiroDialect() { return new ShiroDialect(); }

 

3.thymeleaf首页改动如下:

 

4.页面正常使用shiro标签 欢迎您: 系统管理员 有增加权限 有修改权限

 

3.shiro自定义过滤器

有时候我们希望指定的请求执行特殊的过滤器,例如:

(1) shiro的过滤器链中增加如下策略:

FILTER_CHAIN_DEFINITION_MAP.put("/api/v1/**", "anon, api");

  以/api/v1/开头的所有请求都不用登录,然后会进去api拦截器。

(2)filterMaps 增加api过滤器

// Filter工厂,设置对应的过滤条件和跳转条件 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); // 过滤器 Map filterMaps = new HashMap(); filterMaps.put("authc", new ShiroAuthFilter()); // 增加API接口的过滤器 filterMaps.put("api", new ApiTokenFilter()); shiroFilterFactoryBean.setFilters(filterMaps); // 定义处理规则 shiroFilterFactoryBean.setFilterChainDefinitionMap(setFilterChainDefinitionMap()); return shiroFilterFactoryBean; }

(3)API过滤器如下: 返回false则拒绝处理

import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.apache.shiro.web.filter.PathMatchingFilter; import com.alibaba.fastjson.JSONObject; import com.zd.bx.utils.JSONResultUtil; import com.zd.bx.utils.shiro.APITokenUtils; import com.zd.bx.utils.web.WebUtils; /** * 验证API接口携带的Token * * @author Administrator * */ public class ApiTokenFilter extends PathMatchingFilter { @Override protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { if (!APITokenUtils.isValidToken(request)) { WebUtils.writeJsonToResponse(response, JSONObject.toJSONString(JSONResultUtil.error("访问拒绝,无效token"))); return false; } return true; } }

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有