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>
传统 spring AOP 配置 , 对 spring bean 创建代理 Advisor , 会在业务 Bean 使用 shiro注解, 配置自动代理模式 (对所有 spring 管理 bean 的方法,执行时,检查是否有 shiro注解 )
这里需要注意的是因为shiro的注解是写在方法上面的,而shiro的注解是默认的情况下是通过代理对象是对接口的代理,而接口中的方法是没有注解的,所以我们需要把默认的jdk(接口代理)代理换成CJLB(继承代理),同时我们配置的事务注解也会受到影响,因此我们需要将事务的注解配置也换成CJLB的代理模式。
<!-- 注解管理事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
在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);
}
}
在自定义的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;
}