【Shiro】shiro基於註解的開發
shiro的註解開發實際上是基於AOP思想的。
shiro提供了⼀系列的訪問控制的註解,可以簡化開發過程。
首先我們要導入相關依賴,aspects或者aop的都可以
<!-- 註解加載Controller中,原理是會對Controller做增強,切⼊訪問控制邏輯,所以需要如下依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
1. 配置springmvc的配置文件
注意:是寫在springmvc的配置文件中。
<!-- enable shiro's annotation-->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- ⾃動代理⽣成器,等價於aop:config;
aop:config 或 AutoProxyCreator兩者選其⼀,spring官⽅提醒千萬不要同時使⽤。
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
-->
<aop:config></aop:config>
<!-- 在 此 bean 的 構 建 過 程 中 , 初 始 化 了 ⼀ 些 額 外 功 能 和 piontcut
interceptors.add(new RoleAnnotationMethodInterceptor(resolver));
interceptors.add(new PermissionAnnotationMethodInterceptor(resolver));
interceptors.add(new AuthenticatedAnnotationMethodInterceptor(resolver));
interceptors.add(new UserAnnotationMethodInterceptor(resolver));
interceptors.add(new GuestAnnotationMethodInterceptor(resolver));
-->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
2. 註解的使用
常用註解:
@RequiresAuthenthentication:
表示當前Subject已經通過login進行身份驗證;即 Subject.isAuthenticated()返回 true
@RequiresUser:
表示當前Subject已經身份驗證或者通過記住我登錄的
@RequiresGuest:
表示當前Subject沒有身份驗證或者通過記住我登錄過,即是遊客身份
@RequiresRoles(value = {"admin","user"},logical = Logical.AND):
表示當前Subject需要角色admin和user
@RequiresPermissions(value = {"user:delete","user:b"},logical = Logical.OR):
表示當前Subject需要權限user:delete或者user:b
- 加在類上
@Controller
@RequestMapping("/user")
@RequiresAuthentication //類中的所有⽅法都需要身份認證
@RequiresRoles(value={"manager","admin"},logical= Logical.OR)//類中的所有⽅法都需要⻆⾊,"或"
public class ShiroController {
...
}
- 加在⽅法上
@Controller
@RequestMapping("/user")
public class ShiroController2{
...
@RequiresPermissions({"user:query”,“user:delete"}) //有對應權限,默認是 "且" @RequiresUser //記住我 或 已身份認證
public String hello(){
...
}
@RequiresGuest //遊客身份
public String hello2(){
...
}
}
- 配置修改
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<!-- 不再需要,此時如果身份或權限不通過,會拋出異常,需要異常解析器處理
<property name="loginUrl" value="/user/login/page"/>
<property name="unauthorizedUrl" value="/error.jsp"/>
<property name="filterChainDefinitions">
<value>
/user/query=anon 如下不再需要,登出可以保留,也可以⾃⼰寫handler中subject.logout()
/user/insert=authc,roles["banfu"]
/user/update=authc,perms[""student:update""]
/order/insert=authc,roles["xuewei"]
/user/logout=logout
</value>
</property>-->
</bean>
3. 異常處理
<!-- mvc.xml中:MVC的⾃定義異常處理器,⽤於處理權限或身份認證不通過時的異常處理-->
<bean class="com.siyi.ex.handler.MyExHandler"></bean>
public class MyExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println(ex.getClass()); ex.printStackTrace();//開發時必需ModelAndView mv = new ModelAndView();
if(ex instanceof IncorrectCredentialsException || ex instanceof UnknownAccountException){
//跳轉登錄⻚⾯,重新登錄mv.setViewName("redirect:/user/login");
}else if(ex instanceof UnauthorizedException){// ⻆⾊不⾜
//跳轉權限不⾜的⻚⾯
mv.setViewName("redirect:/user/perms/error");
}else if(ex instanceof UnauthenticatedException){//沒有登錄 沒有合法身份
//跳轉登錄⻚⾯,重新登錄
mv.setViewName("redirect:/user/login");
}
return mv;
}
}