springboot集成shiro权限控制框架--记录

一、pom.xml引入jar包

        <!-- shiro -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-all</artifactId>
			<version>1.6.0</version>
		</dependency>
		<dependency>
			<groupId>com.github.theborakompanioni</groupId>
			<artifactId>thymeleaf-extras-shiro</artifactId>
			<version>2.0.0</version>
		</dependency>

二、加入shiro配置类:ShiroConfig.java

package com.example.demo.shiro;

import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.WebSecurityManager;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;

@Configuration
public class ShiroConfig {
	@Value("${redis.host}")
	private String redis_host;

	@Value("${redis.port}")
	private int redis_port;

	@Bean
	@ConditionalOnMissingBean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
		defaultAAP.setProxyTargetClass(true);
		return defaultAAP;
	}

	// cacheManager 缓存 redis实现 使用的是shiro-redis开源插件
	public RedisCacheManager cacheManager() {
		RedisCacheManager redisCacheManager = new RedisCacheManager();
		redisCacheManager.setRedisManager(redisManager());
		return redisCacheManager;
	}

	// 配置shiro redisManager 使用的是shiro-redis开源插件
	public RedisManager redisManager() {
		RedisManager redisManager = new RedisManager();
		redisManager.setHost(redis_host);
		redisManager.setPort(redis_port);
		redisManager.setExpire(1800);// 配置缓存过期时间 30分钟
		redisManager.setTimeout(0);
		// redisManager.setPassword(password);
		return redisManager;
	}

	// SessionManager 使用的是shiro-redis开源插件
	@Bean
	public DefaultWebSessionManager sessionManager() {
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		// 重定向url去除jssessionid
		sessionManager.setSessionIdUrlRewritingEnabled(false);
		sessionManager.setSessionDAO(redisSessionDAO());
		return sessionManager;
	}

	// RedisSessionDAO shiro sessionDao层的实现 通过redis 使用的是shiro-redis开源插件
	@Bean
	public RedisSessionDAO redisSessionDAO() {
		RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
		redisSessionDAO.setRedisManager(redisManager());
		return redisSessionDAO;
	}

	// 用于thymeleaf模板使用shiro标签
	@Bean
	public ShiroDialect shiroDialect() {
		return new ShiroDialect();
	}

	// 将自己的验证方式加入容器
	@Bean
	public CustomRealm myShiroRealm() {
		return new CustomRealm();
	}

	// 加入缓存,防止doGetAuthorizationInfo执行两次
	@Bean
	public EhCacheManager getCache() {
		return new EhCacheManager();
	}

	// 权限管理配置
	@Bean
	public WebSecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		// 设置realm
		securityManager.setRealm(myShiroRealm());
		// 设置普通缓存
		// securityManager.setCacheManager(getCache());
		// 自定义缓存实现 使用redis
		securityManager.setCacheManager(cacheManager());
		// 自定义session管理 使用redis
		securityManager.setSessionManager(sessionManager());
		return securityManager;
	}

	// 过滤器,设置对应的过滤条件和跳转条件
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(WebSecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);

		// 登录
		shiroFilterFactoryBean.setLoginUrl("/user/login");
		// 首页
		shiroFilterFactoryBean.setSuccessUrl("/getuser/1");
		// 错误页面,认证不通过跳转
		shiroFilterFactoryBean.setUnauthorizedUrl("/user/error");

		Map<String, String> map = new HashMap<>();
		// 登出
		map.put("/user/logout", "logout");
		// 忽略地址
		map.put("/favicon.ico", "anon");
		map.put("/user/login", "anon");
		map.put("/user/dologin", "anon");
		// 对所有用户认证
		map.put("/**", "authc");

		shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
		return shiroFilterFactoryBean;
	}

	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(WebSecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}
}

三、加入shiro自定义权限配置类:CustomRealm.java

package com.example.demo.shiro;

import java.util.HashMap;

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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.example.demo.mapper.UserMapper;

public class CustomRealm extends AuthorizingRealm {
	@Autowired
	private UserMapper userMapper;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		// 获取登录用户名
		String name = (String) principalCollection.getPrimaryPrincipal();
		// 查询用户名称
		HashMap<String, Object> user = userMapper.findByName(name);
		// 添加角色和权限
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

		// for (Role role : user.getRoles()) {
		// // 添加角色
		// simpleAuthorizationInfo.addRole(role.getRoleName());
		// // 添加权限
		// for (Permissions permissions : role.getPermissions()) {
		// simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
		// }
		// }

		// 添加角色
		simpleAuthorizationInfo.addRole("admin");
		// 添加权限
		simpleAuthorizationInfo.addStringPermission("add");
		simpleAuthorizationInfo.addStringPermission("query");

		return simpleAuthorizationInfo;

	}

	/**
	 * @MethodName doGetAuthenticationInfo
	 * @Description 认证配置类
	 * @Param [authenticationToken]
	 * @Return AuthenticationInfo
	 * @Author WangShiLin
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
		if (StringUtils.isEmpty(authenticationToken.getPrincipal())) {
			return null;
		}
		// 获取用户信息
		String name = authenticationToken.getPrincipal().toString();
		// 查询用户名称
		HashMap<String, Object> user = userMapper.findByName(name);
		if (user == null) {
			// 这里返回后会报出对应异常
			return null;
		} else {
			// 这里验证authenticationToken和simpleAuthenticationInfo的信息
			SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.get("password").toString(), getName());
			return simpleAuthenticationInfo;
		}
	}
}

四、基本使用方法

1.登录方法

    @RequestMapping("/user/dologin")
	@ResponseBody
	public String dologin(@RequestParam(value = "name") String name, @RequestParam(value = "password") String password) {
		if (StringUtils.isEmpty(name) || StringUtils.isEmpty(password)) {
			return "请输入用户名和密码!";
		}

		// 用户认证信息
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(name, password);

		try {
			// 进行验证,这里可以捕获异常,然后返回对应信息
			subject.login(usernamePasswordToken);
			// subject.checkRole("admin");
			// subject.checkPermissions("query", "add");
		} catch (UnknownAccountException e) {
			return "用户名不存在!";
		} catch (IncorrectCredentialsException e) {
			return "密码不正确!";
		} catch (ExpiredCredentialsException e) {
			return "密码过期!";
		} catch (LockedAccountException e) {
			return "用户被锁定!";
		} catch (DisabledAccountException e) {
			return "用户被禁用!";
		} catch (ExcessiveAttemptsException e) {
			return "登录失败次数过多!";
		} catch (AuthenticationException e) {
			return "登录出现未知错误!";
		} catch (AuthorizationException e) {
			return "没有权限!";
		}
		return "login success";
	}

2.控制器控制权限方法

    @RequiresRoles("admin")
	@RequestMapping("/admin")
	@ResponseBody
	public String admin() {
		return "admin success!";
	}

	@RequiresPermissions("query")
	@RequestMapping("/query")
	@ResponseBody
	public String index() {
		return "index success!";
	}

3.Thymeleaf页面权限控制方法

    权限
	<shiro:hasPermission name="add">增加</shiro:hasPermission>
	<shiro:hasPermission name="update">修改</shiro:hasPermission>
	<shiro:hasPermission name="delete">删除</shiro:hasPermission>
	<shiro:hasPermission name="query">查询</shiro:hasPermission>
	<br>
	角色
	<shiro:hasRole name="admin">admin</shiro:hasRole>
	<shiro:hasRole name="hr">hr</shiro:hasRole>

4.全局异常捕捉

@ControllerAdvice
public class ExceptionFilter {
	@ExceptionHandler
	@ResponseBody
	public String ErrorHandler(Exception e) {
		return "未知异常!原因是" + e;
	}

	@ExceptionHandler
	@ResponseBody
	public String ErrorHandler(AuthorizationException e) {
		return "没有通过权限验证!";
	}

}

猜你喜欢

转载自blog.csdn.net/hjl0722/article/details/109640759
今日推荐