全选的注解能够放到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是代理的代理。