Apache Shiro基于注解实现细粒度权限控制

本文介绍了如何使用Apache Shiro的注解在Spring应用中实现细粒度权限控制。首先,需要在applicationContext.xml中配置,启用Shiro注解,并将代理模式切换为CGLIB以处理接口方法上的注解。接着,在Service层的方法上添加如RequiresAuthentication、RequiresGuest等Shiro注解。最后,自定义Realm类并重写doGetAuthorizationInfo()方法,将用户权限信息存储到SecurityManager,以进行权限校验。若权限不足,系统会抛出UnauthorizedException。
摘要由CSDN通过智能技术生成

1.在applicationContext.xml中配置,激活shiro的注解。

   <!-- 配置shiro注解 -->
	<bean
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
		depends-on="lifecycleBeanPostProcessor">
        //将默认的JDK代理模式转换成CJLB代理模式
		<property name="proxyTargetClass" value="true"></property>
	</bean>
 
	<bean
		class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" />
	</bean>

需要注意的是因为shiro的注解是写在方法上面的,而shiro的注解是默认的情况下是通过代理对象是对接口的代理,而接口中的方法是没有注解的,所以我们需要把默认的jdk(接口代理)代理换成CJLB(继承代理),同时我们配置的事务注解也会受到影响,因此我们需要将事务的注解配置也换成CJLB的代理模式。

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

2.在service层中的方法上添加shiro的注解。

@Service
@Transactional
public class CourierServiceImpl implements CourierService {
 
	// 注入DAO 对象
	@Autowired
	private CourierRepository courierRepository;
 
	@Override
	@RequiresRoles("base")
	public void save(Courier courier) {
		courierRepository.save(courier);
	}
}

shiro的5个常用注解如下:

  • RequiresAuthentication

使用该注解标注的类,实例,方法在访问或调用时,当前Subject必须在当前session中已经过认证。

  • RequiresGuest

使用该注解标注的类,实例,方法在访问或调用时,当前Subject可以是“gust”身份,不需要经过认证或者在原先的session中存在记录。

  • RequiresPermissions

当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。

  • RequiresRoles

当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法。如果当天Subject不同时拥有所有指定角色,则方法不会执行还会抛出AuthorizationException异常。

  • RequiresUser

当前Subject必须是应用的用户,才能访问或调用被该注解标注的类,实例,方法。
3.在自定义的realm类中重写doGetAuthorizationInfo()方法,将登陆用户的授权和角色信息存入到SecurityManager中,这样SecutityManager就会将用户的权限或角色与注解所需要的进行对比,当权限不足的时候就会抛出org.apache.shiro.authz.UnauthorizedException。

    @Override
	// 授权
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		SimpleAuthorizationInfo simInfo = new SimpleAuthorizationInfo();
		//根据当前登录的用户查询角色和权限信息
		Subject subject = SecurityUtils.getSubject();
		User user = (User) subject.getPrincipal();
		//调用业务层,查询角色信息
		List<Role> roles = rolesService.findByUser(user);
		//为授权对象加入角色
		for (Role role : roles) {
			simInfo.addRole(role.getKeyword());
		}
		
		//调用业务层,查询用户权限
		List<Permission> permissions=perissionService.findByUser(user);
		for (Permission permission : permissions) {
			simInfo.addStringPermission(permission.getKeyword());
		}
		return simInfo;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wunianisme

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值