全選的註解能夠放到Controller層方法上,也能夠放到Service層方法上。java
在原有的基礎上添加一個Serviceweb
public class ShiroService { @RequiresRoles({"admin"}) public void shiroServiceMethod() { System.out.println("Test ShiroServiceMethod, time: " + new Date()); } }
在IOC 容器中進行聲明spring
<bean id="shiroService" class="com.java.shiro.services.ShiroService"></bean>
添加對應的Controller 並注入beanapache
package com.java.shiro.realms; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.java.shiro.services.ShiroService; @Controller @RequestMapping("/shiro") public class ShiroHandler { @Autowired private ShiroService shiroService; @RequestMapping("/shiroMethod") public String shiroServiceMethod(){ shiroService.shiroServiceMethod(); return "redirect:/list.jsp"; } @RequestMapping("/login") public String login(@RequestParam("userName") String userName, @RequestParam("password") String password) { Subject currentUser = SecurityUtils.getSubject(); if (!currentUser.isAuthenticated()) { UsernamePasswordToken token = new UsernamePasswordToken(userName, password); token.setRememberMe(true); try { currentUser.login(token); } catch (AuthenticationException e) { System.out.println("登陸失敗:" + e.getMessage()); } } return "redirect:/list.jsp"; } }
在list.jsp中添加app
<a href="shiro/shiroMethod">Test ShiroMethod</a> <br><br>
測試,jsp
使用admin登陸時能夠正常訪問,使用user登陸時會報錯測試
org.apache.shiro.authz.AuthorizationException: Not authorized to invoke method: public void com.java.shiro.services.ShiroService.shiroServiceMethod()ui
對於異常能夠使用 spring 的聲明式異常搞出一個錯誤頁面,使用註解 @ExceptionHandler 還有一個叫@ControllerAdvicespa
這裏有一個問題要注意:3d
在Service方法上使用註解 @Transactional 即在方法開始的時候會有事務,這個時候這個Service已是一個代理對象,
這個是有把 權限註解加到 Service上是很差用的,會發生類型轉換異常。須要加到Controller上,由於不可以讓Service是代理的代理。