中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot+mybatis-plus整合shiro和redis

發布時間:2020-07-26 10:06:23 來源:網絡 閱讀:1193 作者:nineteens 欄目:編程語言

  整合shiro以及將session存入reids中,導入shiro-redis包,就不用自己實現怎么往redis中存session了。現在一般都是前后端分離的項目,后臺返回統一的格式給前端

  pom

  xsi:schemaLocation=

  4.0.0

  org.springframework.boot

  spring-boot-starter-parent

  2.1.6.RELEASE

  com.pwl

  springboot-shiro

  0.0.1-SNAPSHOT

  springboot-shiro

  Demo project for Spring Boot

  1.8

  org.springframework.boot

  spring-boot-starter-web

  org.springframework.boot

  spring-boot-starter-test

  test

  org.apache.shiro

  shiro-spring-boot-starter

  1.4.0

  mysql

  mysql-connector-java

  com.baomidou

  mybatis-plus-boot-starter

  2.2.0

  com.zaxxer

  HikariCP

  org.apache.velocity

  velocity-engine-core

  2.0

  org.crazycake

  shiro-redis

  2.4.2.1-RELEASE

  org.apache.shiro

  shiro-core

  redis.clients

  jedis

  2.7.2

  org.springframework.boot

  spring-boot-maven-plugin

  認證類,我用的是mybatis-plus

  package com.pwl.shiro.ream;

  import com.baomidou.mybatisplus.mapper.EntityWrapper;

  import com.baomidou.mybatisplus.mapper.Wrapper;

  import com.pwl.shiro.entity.SysUser;

  import com.pwl.shiro.service.SysPermissionService;

  import com.pwl.shiro.service.SysUserService;

  import org.apache.shiro.authc.*;

  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.slf4j.Logger;

  import org.slf4j.LoggerFactory;

  import org.springframework.beans.factory.annotation.Autowired;

  import java.util.ArrayList;

  import java.util.List;

  /**

  * @author Pan Weilong

  * @date 2019/6/20 20:11

  * @description: 接口.

  */

  public class UserRealm extends AuthorizingRealm{

  private static final Logger LOGGER = LoggerFactory.getLogger(UserRealm.class);

  @Autowired

  private SysUserService sysUserService;

  @Autowired

  private SysPermissionService sysPermissionService;

  /**

  * 授權

  *

  * @param principals

  * @return

  */

  @Override

  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

  SysUser sysUser = (SysUser) principals.getPrimaryPrincipal();

  //List sysPermissions = sysPermissionService.selectPermissionByUserId(sysUser.getUserId());

  List sysPermissions=new ArrayList<>();

  sysPermissions.add("systemUserAdd");

  SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

  info.addStringPermissions(sysPermissions);

  LOGGER.info("doGetAuthorizationInfo");

  return info;

  }

  /**

  * 認證

  *

  * @param authenticationToken

  * @return

  * @throws AuthenticationException

  */

  @Override

  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

  UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

  Wrapper objectWrapper = new EntityWrapper<>();

  objectWrapper.eq("user_name",token.getUsername());

  SysUser sysUser = sysUserService.selectOne(objectWrapper);

  if (sysUser == null) {

  return null;

  }

  LOGGER.info("doGetAuthenticationInfo");

  return new SimpleAuthenticationInfo(sysUser, sysUser.getPassword().toCharArray(), ByteSource.Util.bytes(sysUser.getSalt()), getName());

  }

  }

  shiro配置類,很重要

  package com.pwl.shiro.config;

  import com.pwl.shiro.ream.UserRealm;

  import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

  import org.apache.shiro.session.mgt.SessionManager;

  import org.apache.shiro.spring.web.ShiroFilterFactoryBean;

  import org.apache.shiro.web.mgt.DefaultWebSecurityManager;

  import org.apache.shiro.web.servlet.SimpleCookie;

  import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;

  import org.crazycake.shiro.RedisCacheManager;

  import org.crazycake.shiro.RedisManager;

  import org.crazycake.shiro.RedisSessionDAO;

  import org.springframework.context.annotation.Bean;

  import org.springframework.context.annotation.Configuration;

  import java.util.LinkedHashMap;

  import java.util.Map;

  /**

  * @author Pan Weilong

  * @date 2019/6/20 20:10

  * @description: 接口.

  */

  @Configuration

  public class ShiroConfig {

  /**

  * 憑證匹配器

  *

  * @return

  */

  @Bean

  public HashedCredentialsMatcher hashedCredentialsMatcher() {

  HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();

  //md5加密

  hashedCredentialsMatcher.setHashAlgorithmName("md5");

  //加密1次

  hashedCredentialsMatcher.setHashIterations(1);

  return hashedCredentialsMatcher;

  }

  /**

  * 自定義realm

  *

  * @return

  */

  @Bean

  public UserRealm userRealm() {

  UserRealm userRealm = new UserRealm();

  userRealm.setCredentialsMatcher(hashedCredentialsMatcher());

  return userRealm;

  }

  /**

  * 安全管理器

  * 注:使用shiro-spring-boot-starter 1.4時,返回類型是SecurityManager會報錯,直接引用shiro-spring則不報錯

  *

  * @return

  */

  @Bean

  public DefaultWebSecurityManager securityManager() {

  DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

  securityManager.setRealm(userRealm());

  securityManager.setSessionManager(sessionManager());

  return securityManager;

  }

  /**

  * @Author

  * @Description redis緩存

  * @Date 21:32 2019/6/23

  * @Param []

  * @return org.crazycake.shiro.RedisManager

  **/

  @Bean

  public RedisManager redisManager(){

  RedisManager redisManager = new RedisManager();

  redisManager.setHost("127.0.0.1");

  redisManager.setPort(6379);

  //失效時間30分鐘

  redisManager.setExpire(1800);

  return redisManager;

  }

  @Bean

  public RedisSessionDAO redisSessionDAO(){

  RedisSessionDAO redisSessionDAO = new RedisSessionDAO();

  redisSessionDAO.setRedisManager(redisManager());

  //存入redis前綴

  redisSessionDAO.setKeyPrefix("redis_");

  return redisSessionDAO;

  }

  @Bean

  public RedisCacheManager redisCacheManager(){

  RedisCacheManager redisCacheManager = new RedisCacheManager();

  redisCacheManager.setRedisManager(redisManager());

  return redisCacheManager;

  }

  @Bean

  public SessionManager sessionManager() {

  SessionManager sessionManager =new ShiroSessionManager();

  //設置過期時間ms

  ((DefaultWebSessionManager) sessionManager).setGlobalSessionTimeout(1800000);

  //刪除無效的session

  ((DefaultWebSessionManager) sessionManager).setDeleteInvalidSessions(Boolean.TRUE);

  //重寫url

  ((DefaultWebSessionManager) sessionManager).setSessionIdUrlRewritingEnabled(Boolean.TRUE);

  SimpleCookie simpleCookie = new SimpleCookie();

  simpleCookie.setName("loginUser");

  //設置cookie

  ((DefaultWebSessionManager) sessionManager).setSessionIdCookie(simpleCookie);

  ((DefaultWebSessionManager) sessionManager).setSessionDAO(redisSessionDAO());

  ((DefaultWebSessionManager) sessionManager).setCacheManager(redisCacheManager());

  return sessionManager;

  }

  /**

  * 設置過濾規則

  *

  * @param securityManager

  * @return

  */

  @Bean

  public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {

  ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

  shiroFilterFactoryBean.setSecurityManager(securityManager);

  shiroFilterFactoryBean.setLoginUrl("/login");

  shiroFilterFactoryBean.setSuccessUrl("/");

  shiroFilterFactoryBean.setUnauthorizedUrl("/unauth");

  //注意此處使用的是LinkedHashMap,是有順序的,shiro會按從上到下的順序匹配驗證,匹配了就不再繼續驗證

  //所以上面的url要苛刻,寬松的url要放在下面,尤其是"/**"要放到最下面,如果放前面的話其后的驗證規則就沒作用了。

  Map filterChainDefinitionMap = new LinkedHashMap<>();

  filterChainDefinitionMap.put("/static/**", "anon");

  filterChainDefinitionMap.put("/login", "anon");

  filterChainDefinitionMap.put("/captcha.jpg", "anon");

  filterChainDefinitionMap.put("/favicon.ico", "anon");

  filterChainDefinitionMap.put("/**", "authc");

  shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

  return shiroFilterFactoryBean;

  }

  }

  為了避免session頻繁從redis中讀取,要重寫方法

  package com.pwl.shiro.config;

  import org.apache.shiro.session.Session;

  import org.apache.shiro.session.UnknownSessionException;

  import org.apache.shiro.session.mgt.SessionKey;

  import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;

  import org.apache.shiro.web.session.mgt.WebSessionKey;

  import javax.servlet.ServletRequest;

  import java.io.Serializable;

  /**

  * @author Pan Weilong

  * @date 2019/6/22 10:40

  * @description: 接口.

  */

  public class ShiroSessionManager extends DefaultWebSessionManager {

  @Override

  protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {

  Serializable sessionId = getSessionId(sessionKey);

  ServletRequest request = null;

  if (sessionKey instanceof WebSessionKey) {

  request = ((WebSessionKey) sessionKey).getServletRequest();

  }

  if (request != null && null != sessionId) {

  Object sessionObj = request.getAttribute(sessionId.toString());

  if (sessionObj != null) {

  return (Session) sessionObj;

  }

  }

  Session session = super.retrieveSession(sessionKey);

  if (request != null && null != sessionId) {

  request.setAttribute(sessionId.toString(), session);

  }

  return session;

  }

  }

  統一異常處理類

  package com.pwl.shiro.exception;

  import com.pwl.shiro.common.ResultVO;

  import org.apache.shiro.authz.UnauthenticatedException;

  import org.apache.shiro.authz.UnauthorizedException;

  import org.slf4j.Logger;

  import org.slf4j.LoggerFactory;

  import org.springframework.beans.BeansException;

  import org.springframework.context.ApplicationContext;

  import org.springframework.context.ApplicationContextAware;

  import org.springframework.web.bind.annotation.ControllerAdvice;

  import org.springframework.web.bind.annotation.ExceptionHandler;

  import org.springframework.web.bind.annotation.ResponseBody;

  import javax.servlet.http.HttpServletRequest;

  /**

  * @Author Pan Weilong

  * @Description 全局異常捕獲

  * @Date 15:11 2019/6/20

  * @Param

  * @return

  **/

  @ControllerAdvice

  public class GlobalExceptionHandler implements ApplicationContextAware {

  private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

  private ApplicationContext applicationContext;

  @ExceptionHandler(value = Exception.class)

  @ResponseBody

  public ResultVO defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {

  if(e instanceof UnauthenticatedException){

  return new ResultVO().returnFail(401,"認證失敗");

  }else if(e instanceof UnauthorizedException){

  return new ResultVO().returnFail(401,"無權限訪問");

  }

  return new ResultVO().returnFail(e.getMessage());

  }

  @Override

  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

  this.applicationContext = applicationContext;

  }

  }

  返回統一的格式

  package com.pwl.shiro.common;

  import java.io.Serializable;

  /**

  * @author Pan Weilong

  * @date 2019/6/20 15:03

  * @description: 結果統一返回

  */

  public class ResultVO implements Serializable {

  private static final long serialVersionUID = 1L;

  public static final int SUCCESS = 200;

  public static final int FAIL = 1;

  private String msg = "success";

  private int code = SUCCESS;

  private T data;

  public ResultVO() {

  super();

  }

  public ResultVO(T data) {

  super();

  this.data = data;

  }

  public ResultVO(T data, String msg) {

  super();

  this.data = data;

  this.msg = msg;

  }

  public ResultVO(Throwable e) {

  super();

  this.msg = e.getMessage();

  this.code = FAIL;

  }

  /**

  *

  * 返回成功

  * @param data

  * @return

  */

  public ResultVO returnSuccess(T data) {

  this.data = data;

  return this;

  }

  /**

  * 無錫人流醫院 http://www.bhnkyy39.com/

  * 返回失敗

  *

  * @param code

  * @param msg

  * @return

  */

  public ResultVO returnFail(Integer code , String msg) {

  this.code = code;

  this.msg = msg;

  return this;

  }

  public ResultVO returnFail(String msg) {

  this.code = 500;

  this.msg = msg;

  return this;

  }

  public String getMsg() {

  return msg;

  }

  public void setMsg(String msg) {

  this.msg = msg;

  }

  public int getCode() {

  return code;

  }

  public void setCode(int code) {

  this.code = code;

  }

  public T getData() {

  return data;

  }

  public void setData(T data) {

  this.data = data;

  }

  }

  controller

  package com.pwl.shiro.controller;

  import com.pwl.shiro.common.ResultVO;

  import com.pwl.shiro.entity.SysUser;

  import org.apache.shiro.SecurityUtils;

  import org.apache.shiro.authc.UsernamePasswordToken;

  import org.apache.shiro.authz.UnauthenticatedException;

  import org.apache.shiro.subject.Subject;

  import org.springframework.web.bind.annotation.GetMapping;

  import org.springframework.web.bind.annotation.PostMapping;

  import org.springframework.web.bind.annotation.RequestBody;

  import org.springframework.web.bind.annotation.RestController;

  import javax.servlet.http.HttpServletRequest;

  /**

  * @author Pan Weilong

  * @date 2019/6/20 21:00

  * @description: 接口.

  */

  @RestController

  public class LonginController {

  @GetMapping("/login")

  public ResultVO login(HttpServletRequest request){

  return new ResultVO().returnFail(401,"認證失敗");

  }

  @PostMapping("/login")

  public ResultVO login(@RequestBody SysUser sysUser) {

  Subject user = SecurityUtils.getSubject();

  UsernamePasswordToken token = new UsernamePasswordToken(sysUser.getUserName(), sysUser.getPassword());

  try {

  //shiro幫我們匹配密碼什么的,我們只需要把東西傳給它,它會根據我們在UserRealm里認證方法設置的來驗證

  user.login(token);

  } catch (Exception e) {

  e.printStackTrace();

  throw new UnauthenticatedException();

  }

  return new ResultVO("登錄成功");

  }

  }

  package com.pwl.shiro.controller;

  import com.pwl.shiro.common.ResultVO;

  import com.pwl.shiro.entity.SysUser;

  import com.pwl.shiro.service.SysUserService;

  import org.apache.shiro.authz.annotation.RequiresPermissions;

  import org.springframework.beans.factory.annotation.Autowired;

  import org.springframework.web.bind.annotation.GetMapping;

  import org.springframework.web.bind.annotation.RequestMapping;

  import org.springframework.web.bind.annotation.RestController;

  import java.util.List;

  /**

  *

  * 前端控制器

  *

  *

  * @author pwl

  * @since 2019-06-20

  */

  @RestController

  @RequestMapping("/sysUser")

  public class SysUserController {

  @Autowired

  private SysUserService sysUserService;

  //需要有systemUser權限才能訪問

  @RequiresPermissions("systemUserAdd")

  @GetMapping

  public ResultVO getUserList(){

  List sysUsers = sysUserService.selectList(null);

  return new ResultVO(sysUsers);

  }

  //需要有add權限才能訪問

  @RequiresPermissions("Add")

  @GetMapping("/getList")

  public ResultVO getList(){

  List sysUsers = sysUserService.selectList(null);

  return new ResultVO(sysUsers);

  }

  }

  首次登陸的時候

  然后登陸

  最后訪問需要某些權限的接口

  當用戶沒有權限的時候訪問接口

  貼的部分代碼

  sql及項目地址


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

晋州市| 玉山县| 民权县| 福泉市| 沙湾县| 项城市| 山西省| 山阳县| 辽阳县| 城口县| 双辽市| 建始县| 三原县| 黄大仙区| 当涂县| 弋阳县| 防城港市| 紫阳县| 甘德县| 木里| 秦皇岛市| 大兴区| 屯门区| 沙雅县| 丰顺县| 许昌市| 杭锦旗| 洪洞县| 雅安市| 宜丰县| 永昌县| 盐亭县| 桃江县| 南宫市| 尼木县| 嫩江县| 治多县| 靖江市| 扶绥县| 玛沁县| 巴林左旗|