001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.support.shiro;
017
018import com.jfinal.aop.Invocation;
019import com.jfinal.core.Controller;
020import io.jboot.Jboot;
021import io.jboot.support.shiro.processer.AuthorizeResult;
022import io.jboot.utils.StrUtil;
023import org.apache.shiro.web.util.WebUtils;
024
025import javax.servlet.http.HttpServletRequest;
026
027/**
028 * @author Michael Yang 杨福海 (fuhai999@gmail.com)
029 * @version V1.0
030 */
031public interface JbootShiroInvokeListener {
032
033
034    /**
035     * 通过这个方法,可以用来处理 jwt、sso 等和shiro的整合
036     *
037     * @param inv
038     */
039    AuthorizeResult onInvokeBefore(Invocation inv);
040
041    /**
042     * 通过这个方法,可以用来自定义shiro 处理结果 和 错误逻辑
043     *
044     * @param inv
045     * @param result
046     */
047    void onInvokeAfter(Invocation inv, AuthorizeResult result);
048
049
050    JbootShiroInvokeListener DEFAULT = new JbootShiroInvokeListener() {
051
052
053        private JbootShiroConfig config = Jboot.config(JbootShiroConfig.class);
054
055
056        @Override
057        public AuthorizeResult onInvokeBefore(Invocation inv) {
058            //do nothing
059            return null;
060        }
061
062        @Override
063        public void onInvokeAfter(Invocation inv, AuthorizeResult result) {
064            if (result.isOk()) {
065                inv.invoke();
066                return;
067            }
068
069            int errorCode = result.getErrorCode();
070            switch (errorCode) {
071                case AuthorizeResult.ERROR_CODE_UNAUTHENTICATED:
072                    doProcessUnauthenticated(inv.getController());
073                    break;
074                case AuthorizeResult.ERROR_CODE_UNAUTHORIZATION:
075                    doProcessuUnauthorization(inv.getController());
076                    break;
077                default:
078                    inv.getController().renderError(404);
079            }
080        }
081
082
083        public void doProcessUnauthenticated(Controller controller) {
084            if (StrUtil.isBlank(config.getLoginUrl())) {
085                controller.renderError(401);
086                return;
087            }
088            HttpServletRequest request = controller.getRequest();
089            //保存被拦截的请求 Shiro将在登录成功后跳转到原请求
090            WebUtils.saveRequest(request);
091            controller.redirect(config.getLoginUrl());
092        }
093
094        public void doProcessuUnauthorization(Controller controller) {
095            if (StrUtil.isBlank(config.getUnauthorizedUrl())) {
096                controller.renderError(403);
097                return;
098            }
099            controller.redirect(config.getUnauthorizedUrl());
100        }
101
102    };
103
104}