>  기사  >  Java  >  shiro를 기반으로 한 사용자 정의 주석 확장 - 그림과 텍스트를 통한 자세한 설명

shiro를 기반으로 한 사용자 정의 주석 확장 - 그림과 텍스트를 통한 자세한 설명

php是最好的语言
php是最好的语言원래의
2018-08-09 17:19:091597검색

shiro의 사용자 정의 주석을 기반으로 한 확장

여기에서는 주로 shiro의 사용자 정의 주석 솔루션을 채택합니다. 이 기사에서는 주로 다음과 같은 문제를 해결합니다.

  1. 로직을 통해 페이지를 API 인터페이스와 연결하는 방법.

  2. Shiro의 자체 주석 사용.

  3. 맞춤 주석을 작성하는 방법.

로직을 통해 페이지를 API 인터페이스와 연결하는 방법

테이블 간의 구조적 관계에서 페이지와 인터페이스 테이블은 궁극적으로 권한 테이블과 연결됩니다. (자세한 내용은 이전 기사 "권한" 디자인 토크"를 참조하세요.) .
shiro를 기반으로 한 사용자 정의 주석 확장 - 그림과 텍스트를 통한 자세한 설명이제는 어느 정도 권한 제어를 고려하면서 저렴한 비용을 달성할 수 있는 다른 솔루션으로 교체하기를 희망합니다. 여기서는 두 가지 개념을 소개합니다. 비즈니스 모듈, 운영 유형.

  • 비즈니스 모듈

    • Concept: 시스템의 비즈니스 모듈을 문자열 형식으로 표현할 수 있는 일종의 데이터로 추상화합니다. 예를 들어 역할 관리는 역할 관리에 해당합니다. 사용자 관리는 사용자 관리 등에 해당합니다. '최소 권한의 원칙'을 통해 시스템에 존재하는 비즈니스 모듈을 분할하고 최종적으로 배포 가능한 데이터 배치를 구성합니다.

    • 사용 원칙: API 인터페이스, 페이지 및 기능은 본질적으로 비즈니스 모듈과 논리적으로 관련되어 있습니다. 따라서 API 인터페이스와 페이지(및 기능 포인트)를 논리적으로 일치시켜 페이지가 일치하는지 확인할 수 있습니다. 비즈니스 모듈 관계.

  • Operation type

    • Concept: 시스템의 모든 작업 유형을 일종의 데이터로 추상화합니다. 예를 들어 새로운 추가는 추가 및 할당에 해당합니다. . 해당하는 것은 할당 등입니다. 비즈니스 모듈에 따라 "데이터 라이센스"를 통해 시스템의 모든 작업 유형을 나누고 최종적으로 배포 가능한 데이터 배치를 구성합니다.

    • 사용 원칙: 페이지는 디스플레이, 기능 포인트는 액션, 인터페이스는 최종 액션을 위한 리소스 제공이며, 호출할 리소스는 "비즈니스 모듈"을 통해 결정됩니다. 리소스의 사용량은 "작업 유형"을 통해 결정됩니다. 두 가지를 통해 페이지의 기능 포인트에 의해 트리거된 인터페이스가 인증 범위 내에 있는지 대략적이고 정확하게 확인할 수 있습니다.

이제 이 두 가지 개념이 제안되었으니, 최종 실제 용도는 무엇인지 먼저 다음과 같은 관점에서 생각해 보겠습니다.

  1. 페이지 테이블이나 데이터베이스의 API 인터페이스 테이블에 있는 데이터가 실제이고 유효한가요?

  2. 페이지나 인터페이스의 실제 사용은 기능의 존재 여부 또는 데이터베이스 테이블의 데이터 존재 여부에 따라 결정됩니다.

  3. 권한 구조에서 "제어 개체"를 저장하는 유일한 방법은 데이터베이스입니까?

이러한 질문을 결론부터 살펴보겠습니다. 우선 "제어 개체"의 저장은 데이터베이스에 있을 수도 있고, 코드에 있을 수도 있고, 구성 파일에 있을 필요는 없습니다. ; 그런 다음 두 번째 질문에 답하십시오. 문제는 데이터베이스에 인터페이스 정보가 있지만 서버가 이 인터페이스를 개발하지 않은 경우 데이터베이스 정보 자체에 문제가 있거나 데이터베이스의 새 인터페이스가 다음과 같은 인터페이스를 가지고 있어야 한다는 것입니다. 적용하기 위해 서버에 배포되었습니다. 그런 다음 첫 번째 질문이 있습니다. 그러면 데이터베이스의 "제어 개체"에 대한 테이블의 데이터가 반드시 사실이고 유효한 것은 아닙니다. 그래서 우리는 다음과 같은 해결책을 생각해 낼 수 있습니다

  1. "비즈니스 모듈"과 "작업 유형"의 데이터 정보를 보완하기 위해 인터페이스에서 주석을 사용할 수 있습니다. 두 가지 유형의 정보 모두 상수 클래스에 저장될 수 있습니다.

  2. 데이터베이스에 페이지 테이블 구조와 페이지 기능 테이블 구조를 생성할 때 "비즈니스 모듈" 및 "작업 유형" 필드를 추가하세요.

  3. 데이터베이스의 사전 테이블에 "비즈니스 모듈" 및 "작업 유형" 정보를 저장할 수 있습니다.

  4. 모듈이나 작업을 추가하면 필연적으로 인터페이스가 추가되어 시스템 배포 활동이 발생하게 됩니다. 이러한 작업 및 유지 관리 비용은 테이블 구조를 통해서도 줄일 수 없습니다.

shiro를 기반으로 한 사용자 정의 주석 확장 - 그림과 텍스트를 통한 자세한 설명

그러나 이 솔루션은 강력하지 않은 제어 인터페이스 프로젝트에만 적합합니다. 강력한 제어 인터페이스 프로젝트에서는 막대한 운영 및 유지 관리 비용이 발생하더라도 페이지와 인터페이스를 여전히 바인딩해야 합니다. 또한 인터페이스 라우팅 규칙으로 나눌 수도 있습니다. 예를 들어 /api/page/xxxx/(페이지에만 사용됨), /api/mobile/xxxxx(모바일 단말에만 사용됨)는 사용되는 인터페이스만 분류합니다. 이 클래스 인터페이스는 인증만 수행하지만 인증은 수행하지 않으며, 이는 목적을 달성할 수도 있습니다.

Shiro의 자체 주석 사용

이론적인 아이디어를 승인한 후 나머지는 Apache를 사용하여 Spring에서 Shiro의 보안 프레임워크를 적용합니다. 부팅 환경. Shiro의 다음 주석을 간략하게 설명하십시오.

#🎜 🎜 #@RequiresAuthentication 클래스, 메서드 및 인스턴스에 대해 작동합니다. 호출되면 현재 주체를 인증해야 합니다. @RequiresGuest은 클래스, 메서드 및 인스턴스에 대해 작동합니다. 호출 시 주제는 게스트 상태일 수 있습니다. @RequiresPermissions은 클래스, 메서드 및 인스턴스에 대해 작동합니다. 호출 시 현재 인터페이스에서 프로젝트에 Permission(권한 정보)이 포함되어 있는지 확인해야 합니다. @RequiresRoles은 클래스, 메서드 및 인스턴스에 대해 작동합니다. 호출 시 현재 인터페이스의 Role(역할 정보)이 주체에 포함되어 있는지 확인해야 합니다. @RequiresUser은 클래스, 메서드 및 인스턴스에 대해 작동합니다. 호출 시 주체가 현재 애플리케이션에 있는 사용자인지 여부를 확인해야 합니다.
    /**
     * 1.当前接口需要经过"认证"过程
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresAuthentication
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
    
    /**
     * 2.1.当前接口需要经过权限校验(需包含 角色的查询 或 菜单的查询)
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresPermissions(value={"role:search","menu":"search"},logical=Logical.OR)
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
    
    /**
     * 2.2.当前接口需要经过权限校验(需包含 角色的查询 与 菜单的查询)
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresPermissions(value={"role:search","menu":"search"},logical=Logical.OR)
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
    
    /**
     * 3.1.当前接口需要经过角色校验(需包含admin的角色)
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresRoles(value={"admin"})
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
    
    /**
     * 3.2.当前接口需要经过角色与权限的校验(需包含admin的角色,以及角色的查询 或 菜单的查询)
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresRoles(value={"admin"})
    @RequiresPermissions(value={"role:search","menu":"search"},logical=Logical.OR)
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
주석 이름 함수
실제 사용 프로세스에서는 @RequiresPermissions 및 @RequiresAuthentication만 사용하면 됩니다. 이 주석으로 충분합니다. , 우리는 페이지와 API 인터페이스 간의 관계를 분리하기 위해 비즈니스 모듈과 작업의 조합을 채택했는데, 이는 Apache Shiro의 접근 방식과 정확히 동일합니다. 하지만 역할의 조합이 너무 많고 인터페이스에서 역할 이름을 고유하게 표현할 수 없기 때문에 @RequiresRoles를 최대한 사용하지 않으려고 합니다(인터페이스가 특정 역할에 속한다고 지정하기는 어렵지만 인터페이스가 특정 비즈니스 모듈에 속해 있음을 확실히 알 수 있습니다.) 일부 작업 )

이제 전체 작업 프로세스를 검토해 보겠습니다.

shiro를 기반으로 한 사용자 정의 주석 확장 - 그림과 텍스트를 통한 자세한 설명

맞춤 주석 작성 방법

하지만 shiro에 이 5개의 주석을 두는 것만으로는 충분하지 않습니다. 실제 사용 과정에서는 필요에 따라 권한 인증에 고유한 비즈니스 로직을 추가하여 사용자 정의 주석을 사용할 수 있습니다. 이 방법은 Apache Shiro뿐만 아니라 Hibernate Validator, SpringMVC와 같은 다른 많은 프레임워크에도 적용 가능하며 Aop에서 권한을 확인하는 확인 시스템을 작성할 수도 있는데 이는 문제가 되지 않습니다. 따라서 사용자 정의 주석은 다양한 용도로 사용됩니다. 하지만 여기서는 shiro를 기반으로 이에 적합한 맞춤 주석만 구현합니다.

  • 주석 처리 클래스 정의

  • /**
     * 用于认证的接口的注解,组合形式默认是“或”的关系
     */
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Auth {
        /**
         * 业务模块
         * @return
         */
        String[] module();
        /**
         * 操作类型
         */
        String[] action();
    
    }
  • 주석 처리 클래스 정의# 🎜 🎜#

    /**
     * Auth注解的操作类
     */
    public class AuthHandler extends AuthorizingAnnotationHandler {
    
    
        public AuthHandler() {
            //写入注解
            super(Auth.class);
        }
    
        @Override
        public void assertAuthorized(Annotation a) throws AuthorizationException {
            if (a instanceof Auth) {
                Auth annotation = (Auth) a;
                String[] module = annotation.module();
                String[] action = annotation.action();
                //1.获取当前主题
                Subject subject = this.getSubject();
                //2.验证是否包含当前接口的权限有一个通过则通过
                boolean hasAtLeastOnePermission = false;
                for(String m:module){
                    for(String ac:action){
                        //使用hutool的字符串工具类
                        String permission = StrFormatter.format("{}:{}",m,ac);
                        if(subject.isPermitted(permission)){
                            hasAtLeastOnePermission=true;
                            break;
                        }
                    }
                }
                if(!hasAtLeastOnePermission){
                    throw new AuthorizationException("没有访问此接口的权限");
                }
    
            }
        }
    }
    shiro 차단 처리 클래스 정의
  • /**
     * 拦截器
     */
    public class AuthMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
    
    
        public AuthMethodInterceptor() {
            super(new AuthHandler());
        }
    
        public AuthMethodInterceptor(AnnotationResolver resolver) {
            super(new AuthHandler(), resolver);
        }
    
        @Override
        public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
            // 验证权限
            try {
                ((AuthHandler) this.getHandler()).assertAuthorized(getAnnotation(mi));
            } catch (AuthorizationException ae) {
                if (ae.getCause() == null) {
                    ae.initCause(new AuthorizationException("当前的方法没有通过鉴权: " + mi.getMethod()));
                }
                throw ae;
            }
        }
    }
# 🎜🎜#shiro의 aop 측면 클래스 정의
  • /**
     * shiro的aop切面
     */
    public class AuthAopInterceptor extends AopAllianceAnnotationsAuthorizingMethodInterceptor {
        public AuthAopInterceptor() {
            super();
            // 添加自定义的注解拦截器
            this.methodInterceptors.add(new AuthMethodInterceptor(new SpringAnnotationResolver()));
        }
    }

shiro의 사용자 정의 주석 시작 클래스 정의
    #🎜🎜 ##🎜 🎜 #
    /**
     * 启动自定义注解
     */
    public class ShiroAdvisor extends AuthorizationAttributeSourceAdvisor {
    
        public ShiroAdvisor() {
            // 这里可以添加多个
            setAdvice(new AuthAopInterceptor());
        }
    
        @SuppressWarnings({"unchecked"})
        @Override
        public boolean matches(Method method, Class targetClass) {
            Method m = method;
            if (targetClass != null) {
                try {
                    m = targetClass.getMethod(m.getName(), m.getParameterTypes());
                    return this.isFrameAnnotation(m);
                } catch (NoSuchMethodException ignored) {
    
                }
            }
            return super.matches(method, targetClass);
        }
    
        private boolean isFrameAnnotation(Method method) {
            return null != AnnotationUtils.findAnnotation(method, Auth.class);
        }
    }
  • 전체 아이디어 순서: 정의

    주석 클래스

    (비즈니스에서 사용할 수 있는 변수 정의) -> 정의
  • 주석 처리 클래스
( 주석의 변수를 통해 비즈니스 로직 처리 수행) ->define
interceptor of Annotation->define aop's 관점 클래스->마지막으로 shiro의 사용자 정의 정의 주석 활성화 클래스 . 다른 사용자 정의 주석에 대한 작성 아이디어는 이와 유사합니다. 관련 권장사항: 사용자 정의 주석 매핑 thinkPHP21 사용자 정의 태그 라이브러리 가져오기 방법에 대한 자세한 설명

# 🎜 🎜#Java의 사용자 정의 주석에 대한 자세한 소개

shiro 인증 구현 세부 정보

위 내용은 shiro를 기반으로 한 사용자 정의 주석 확장 - 그림과 텍스트를 통한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.