第一种使用shiro的注解方式:
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true" /> </bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean>
配置上,在方法头上加上注解就可以了,网上资料很多,就不详说了
使用自定义注解
先上自定义注解:
package com.isoftstone.common.permission; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD})//适用的地方 有 方法上 类上等 public @interface CheckPermission { String [] permission();//可以传多个权限标示 }
注解使用:
/** * 保存 * @param 基本用户信息 * @param 角色id * @return * @author {huzhe} */ @RequestMapping(value = "/saveUser") @CheckPermission(permission={BusinessPermissionLabel.permission_addChildAccount}) public OperationPrompt saveUser(UserBasicInfo userbaseInfo,String addRoleIds) {
多个权限标示使用逗号隔开;
第二种:使用spring aop 方法验证 基于上边的自定义
使用shiro验证是否标示是否有权限
currentUser.isPermitted(per)
package com.isoftstone.common.permission; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.subject.Subject; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component //次方法根据spring aop贴入方法 进行权限验证 public class PermissionInterceptor { @Around("execution(* com.isoftstone.dcf.portal..*(..)) && @annotation(checkPermission)") public Object doInterceptor(ProceedingJoinPoint pjp,CheckPermission checkPermission) throws Throwable{ long time = new java.util.Date().getTime(); boolean isPermissioin = false; Subject currentUser = SecurityUtils.getSubject(); //没有获得注解 及不需要权限-- 则直接运行 if(null!=checkPermission){ String [] permission = checkPermission.permission(); for(String per:permission){ //当前登录人 具有权限 if(currentUser.isPermitted(per)){ isPermissioin = true; break; } } }else{ isPermissioin = true; } System.out.println("(AOP)拦截到了:"+pjp.getSignature().getName()+"方法所用时间:"+time+"到"+new java.util.Date().getTime()); if(isPermissioin){ //有执行方法或权限不拦截 return pjp.proceed(); }else{ //抛出无权限异常 throw new AuthorizationException(); } } }
需要在spring配置文件中开始aop注解:
<!-- 打开aop使用aop进行权限验证 --> <aop:aspectj-autoproxy />
方式3:使用spring mvc拦截所有url验证:
<!-- 使用spring mvc拦截器进行权限验证 --> <mvc:interceptors> <bean class="com.isoftstone.common.permission.PermissionInterceptorAdapter" /> </mvc:interceptors>
这个方法实现大致一样:
package com.isoftstone.common.permission; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.subject.Subject; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; //次方法根据spring mvc拦截器进行权限验证 public class PermissionInterceptorAdapter extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handler2=(HandlerMethod) handler; CheckPermission checkPermission = handler2.getMethodAnnotation(CheckPermission.class); long time = new java.util.Date().getTime(); boolean isPermissioin = false; Subject currentUser = SecurityUtils.getSubject(); //没有获得注解 及不需要权限-- 则直接运行 if(null!=checkPermission){ String [] permission = checkPermission.permission(); for(String per:permission){ //当前登录人 具有权限 if(currentUser.isPermitted(per)){ isPermissioin = true; break; } } }else{ isPermissioin = true; } System.out.println("拦截到了mvc方法:"+handler2.getMethod()+"方法所用时间:"+time+"到"+new java.util.Date().getTime()); if(isPermissioin){ //有执行方法或权限不拦截 return true; }else{ //跑出无权限异常 throw new AuthorizationException(); } } }
除了spring和shiro使用的包:
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.0</version> </dependency>
spring自定义异常拦截:
package com.isoftstone.common.exception; import java.io.IOException; import java.sql.SQLException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.UnauthorizedException; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import com.isoftstone.common.bo.PermissioinPage; /** * 自定义权限异常处理 * @author Administrator * */ @Component public class MyHandlerExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) { //是否为ajax请求 String requestType = request.getHeader("X-Requested-With"); if(exception instanceof AuthorizationException){ response.setStatus(413);//无权限异常 主要用于ajax请求返回 response.addHeader("Error-Json", "{code:413,msg:'nopermission',script:''}"); response.setContentType("text/html;charset=utf-8"); if("XMLHttpRequest".equals(requestType)){ return new ModelAndView(); } return new ModelAndView("redirect:/html/413.html"); } return null; }