기능적 권한 검증을 구현하는 방법에는 여러 가지가 있습니다. 하나는 인터셉터를 사용하여 요청을 가로 채고 다른 하나는 AOP를 사용하여 예외를 던지는 것입니다.
먼저 인터셉터를 사용하여 로그인 인터페이스가 로그인되지 않을 때 로그인 인터페이스로 점프하는 기능을 실현하십시오. AOP는 여기에 사용되지 않지만 AOP가 일반적으로 서비스 계층 메소드에 들어가기 때문에 인터셉터가 차단됩니다. 인터셉터는 컨트롤러 계층으로부터의 요청을 가로 채기 때문입니다. 또한 프로세서 자체로 요청의 전달을 직접 방해하고보기를 반환 할 수 있지만 AOP는 할 수 없습니다.
1. 인터셉터를 사용하여 로그인 인터페이스로 로그인하지 않을 때 로그인 인터페이스로 점프하는 기능을 실현하십시오.
1.1 인터셉터 Security Interceptor
패키지 com.jykj.demo.filter; import java.io.printwriter; import javax.servlet.http.httpservletrequest; import javax.servlet.http.http.htttp.httpervletresponse; import javax.servlet.http.httpervletresponse; import javax.servlet.http.httpsession; import org.springframework.web.servlet.handlerinterceptor; import org.sprameframework.web.servlet.modelandview; import com.astjson.json; import com.jykj.demo.util.helper; import; com.jykj.demo.util.result; 공개 클래스 Security Interceptor는 핸들러 interceptor {@override public boolean prehandle (httpservletrequest request, httpservletresponse 응답, 개체 핸들러) exception { System.out.println ( "SecurityInterceptor :"+request.getContextPath ()+","+request.getRequestUri ()+","+request.getMethod ()); httpsession session = request.getSession (); if (session.getAttribute (helper.session_user) == null) {System.out.println ( "AuthorizationException : 로그인되지 않음!" +request.getMethod ()); if ( "post".EqualSeignoreCase (request.getMethod ())) {response.setContentType ( "text/html; charset = utf-8"); printwriter out = response.getwriter (); out.write (json.tojsonstring (새 결과 (False, "Not Loged!"))); out.flush (); out.close (); } else {response.sendRedirect (request.getContextPath ()+"/로그인"); } false를 반환합니다. } else {return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // todo 자동 생성 메소드 스텁}}1.2.spring-mvc.xml (인터셉터 구성 부분)
<!-$ {webApproot}/resources directory에서 정적 자원을 효율적으로 제공함으로써 HTTP/Resources/**에 대한 요청을 처리합니다. <mvc : resources mapping = "/resources/**"위치 = "/resources/"/> <mvc : interceptors> <mvc : mvc : mvcing path = mvc : 매핑 구조 = "/** <! AS/TEST/LOGIN-> <MVC : 매핑 경로 = "/**/*. ASPX"/> <!-접미사 .ASPX를 사용하여 요청을 가로 채기. <mvc : 제외 매핑 경로 = "/register"/> <ean> </bean> </mvc : interceptor> </mvc : interceptors>여기에 지정해야합니다. 인터셉터에 의해 가로 채는 경로는 바람직하게는 접미사 이름을 갖는 것이 바람직합니다. 그렇지 않으면 일부 정적 리소스 파일은 제어하기가 어렵습니다. 즉, 요청은 .DO 등과 같은 통합 형식이 있어야하므로 일치 및 필터링 속도가 매우 빠릅니다. 그렇지 않은 경우, 예를 들어 모든 요청을 가로 채기 위해 /**를 사용하면 리소스 파일도 가로 채기 때문에 페이지 렌더링 속도가 매우 느립니다.
2. AOP를 사용하여 기능 권한 검증을 구현하십시오
기능 권한 검증은 인터셉터와 유사하게 구현 될 수 있지만 모든 요청을 가로 채며 권한 확인이 필요하지 않은 요청에 대한 필터링 기능이 양호하지 않습니다. 따라서 필요한 검증을 가로 채는 방법을 지정하기 위해 AOP를 사용하여 구현됩니다.
2.1 허가증
package com.jykj.demo.filter; import java.io.ioexception; import java.lang.reflect.method; import org.aspectj.lang.joinpoint; import org.aspectj.lang.reflect.methodsignature; import org.springframework.bean.bean.antowation com.jykj.demo.annotation.validatepermission; import com.jykj.demo.exception.accessdeniedexception; import com.jykj.demo.service.sysuserRopermservice;/*** 이벤트 로그 섹션, @ValidatePermission을 가진 모든 컨트롤러 및 @ResponseBide를 수행해야합니다. * 권한이없는 경우 AccessDeniedException 예외가 발생하여 컨트롤러에 요청을 전달한 다음 예외 결과를 반환 한 다음 * @Author Administrator */public class armissionAspect {@autowired sysuserRopermservice suseRroperMservice; public void dobefore (joinpoint jp)는 ioexception {system.out.println ( "로그 허가증 이전 :" + jp.getTarget (). getClass (). getName () + "." + jp.getSignature (). getName ()); 메소드 미안 메드 = getSourcemethod (jp); if (soruceMethod! = null) {validatePermission Opera = residmethod.getAntantation (validatePermission.class); if (oper! = null) {int fidx = opera.idx (); Object [] args = jp.getargs (); if (fidx> = 0 && fidx <args.length) {int functionid = (Integer) args [fidx]; 문자열 rs = sysuserRopermservice.permissionValidate (functionId); System.out.println ( "repmissionValidate :"+rs); if (rs.trim (). isempty ()) {return; // normal}}} 새 ac } private method getSourcemethod (joinpoint jp) {method proxymethod = ((methodSignature) jp.getSignature ()). getMethod (); {return jp.getTarget (). getClass (). getMethod (proxyMethod.getName (), proxyMethod.getParameterTypes ()); } catch (nosuchmethodexception e) {e.printstacktrace (); } catch (SecurityException e) {e.printstacktrace (); } return null; }}2.2 사용자 정의 주석 ValidatePermission
package com.jykj.demo.annotation; import java.lang.annotation.documented; import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.restation.restation. import java.lang.annotation.target; 태그 타입 주석. 이 주석에 의해 주석이 붙은 메소드는 권한 확인* /@target (value = elementType.Method) @ReTention (value = retentionPolicy.runtime) @documentEdPublic @Interface validatePermission { /*** @Description이 기능 ID의 매개 변수 인덱스 위치가 첫 번째 매개 변수의 위치에 있음을 나타냅니다. 수행 */ int idx () 기본 0;}참고 : AOP는 컨트롤러의 요청이 아닌 메소드로 절단되므로 방법의 요청을 방해하기 위해보기로 직접 돌아올 수는 없지만 예외를 던지면 메소드의 실행을 방해하는 목적을 달성 할 수 있습니다. 따라서 이전 알림에서 연결 지점 메소드를 직접 반환하면 검증을 통해 연결 지점 메소드가 반환됩니다. 그렇지 않으면 연결 지점 메소드의 실행을 방해하기 위해 사용자 정의 예외 AccessDeniedException이 발생됩니다. 예외 캡처는 시스템의 예외 처리기 (컨트롤러로 간주 될 수 있음)를 통해보기 또는 요청으로 캡처 및 리디렉션 될 수 있습니다. 이것은 요청을 가로 채기위한 목적을 달성합니다. 따라서 예외 프로세서를 구성해야합니다.
2.3 Spring-MVC.XML (예외 프로세서 구성 및 AOP 구성)
<eAN> <!-<속성 이름 = "defaulterrorView"value = "readiret :/error"> </property>-> <속성 이름 = "ExceptionMappings"> <props> <!-<prop key = "com.jykj.demo.exception.authorizationException"> regin </prop>-> <prop key = "com.jykj.demo.exception.accessdeniedexception"> forward :/accessDenied </propdenied </prop> </props> </property> </bean> <bean id = "agagepermission"/<!-컨트롤러 패키지의 모든 메소드 및 @validatepermission 및 응답 대답으로 기능 허가 검증을 수행합니다. <aop : 측면 ref = "agagpermission"> <aop : pointcut id = "pc"expression = " @annotation (com.jykj.demo.annotation.validatepermission) 및 @annotation (org.springframework.web.bind.annotation.responsebody) 및 execution (*com.jykj.demo.controller. <aop : pointcut-Ref = "pc"method = "dobefore"/> </aop : aspect> </aop : config>
2.4 기능 검증이 필요한 컨트롤러 요청 주석
@RequestMapping (value = "/moduleAccess.do", method = requestMethod.post, croferes = "text/html; charset = utf-8") @ResponseBody @ValidatePermission public String moduleAccess (int fid, 문자열 액션, frmmodule 모듈) {system.out.println ( "+fid+", "+"; int rs = -1; try {if (helper.f_action_create.equals (action)) {rs = moduleservice.access (모듈, Helper.db_action_insert); //module.setmoduleid(rs); module = moduleservice.selectByPrimaryKey (RS); } else if (helper.f_Action_edit.equals (action)) {rs = moduleservice.access (모듈, Helper.db_action_update); module = moduleservice.selectByPrimaryKey (module.getModuleId ()); } else if (helper.f_Action_Remove.equals (action)) {rs = moduleservice.access (모듈, Helper.db_action_delete); } else {return json.tojsonstring (새 결과 (false, "요청 매개 변수 오류 : 조치")); }} catch (예외 e) {e.printstacktrace (); return JSON.TOJSONSTRING (새 결과 (False, "작업 실패, 예외가 발생하고 관리자에게 연락하십시오!")); } if (rs <0) {return json.tojsonstring (새 결과 (False, "작업 실패, 관리자에게 문의하십시오!")); } return JSON.TOJSONSTRING (새 결과 (true, module)); }2.5 컨트롤러 요청 전달 :/AccessDenied Exception Handler Forward :/AccessDenied
@RequestMapping (value = "/accessDenied", produces = "text/html; charset = utf-8")@response bodypublic string accessDenied () {return json.tojsonstring (false, "이것에 대해 작동 할 수있는 허가가 없습니다!});}2.6 요청 확인이 실패하면 위의 컨트롤러가 결과 자체를 반환합니다.
아래 그림과 같이 :
{ "info": "당신은 이것에 대해 운영 할 권한이 없습니다!", "성공": false}
2.7 기능 검증 서비스 예제
/ *** 모듈의 특정 함수에서 현재 사용자의 허가를 확인하십시오* @param functionId* @return 빈 문자열은 허가를 나타냅니다. 그렇지 않으면 오류 메시지입니다* @throws 예외*/ public String exmissionValidate (int functionId) {object o = requestsession (). getAttribute (helper.session_user); // if (o == NULL) 새로 인증 exception (); sysuser loginuser = (sysuser) o; if (loginuser.getUserId () == 1) return ""; try {return mapper.permissionValidate (loginuser.getUserId (), functionId); } catch (예외) {ex.printstacktrace (); "데이터베이스 작업에서 예외가 발생했습니다!"; }} 참고 : 여기서는 컨트롤러 패키지의 모든 메소드와 @ValidatePermission 및 @ResponseBody 주석이있는 하위 포장을 잘라 내고 있습니다. 이것은 확실히 보편적이지 않습니다. @ValidatePermission으로 메소드를 잘라야합니다. 섹션 클래스에서는 메소드에 @ResponseBody 주석이 있는지 판단하여 다른 예외를 던질 것입니다. 위의 예외가 발생하면 위의 예외가 발생하여 JSON 문자열로 돌아갑니다.
그렇지 않으면 또 다른 사용자 정의 예외가 발생하고 요청이 error.jsp와 같은 법적보기로 리디렉션됩니다.
클라이언트를 통해 /moduleAccess.do 요청을 보내십시오. 요청의 해당 방법에는 @ValidatePermission과 @ResponseBody가 모두 있으며 기능 ID 매개 변수 FID가 있으므로 AOP가 메소드를 입력하고 DOBEBEEFORE 알림을 실행하고 기능 매개 변수 FID를 사용하여 사용자 ID와 함께 허가를 확인할 수 있습니다. 확인이 통과되면 프로그램이 계속 실행됩니다. 그렇지 않으면 사용자 정의 예외 AccessDeniedException이 발생합니다. 예외는 시스템에 의해 잡히고 (예외 핸들러를 구성해야 함) 요청이 발행됩니다 :/AccessDenied, 해당 컨트롤러/액세스 인은 요청을 처리하고 확인 실패 정보를 포함하는 JSON을 클라이언트에 반환합니다. /moduleAccess.do 요청을 보냅니다. 확인이 실패하면 /AccessDenied 요청을 전달하면 정상적으로 실행됩니다. 그런 큰 원을 돌아 다니면서 실현되었습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.