• elementui的和前后端分离的微信登陆功能


    理论:

    1.获得微信官方的网址

    2.使用OAuth2.0

    3.登陆需要三步

    获得验证

    返回一个网站

    获得授权

    对象

    获得用户

    对象

     然后登陆的时候会和我们数据库中的袁勇绑定,如果没有就创建,有就关联

    操作:

    1.更改项目配置

    在最后一行添加

    127.0.0.1 bugtracker.itsource.cn

    这是你去官网注册获得的域名这样才能把二维码返回过来,使用回调函数

    2.引入依赖

    <!--httpclient的依赖:-->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.7</version>
            </dependency>
    
            <!--处理json的包
      https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>

    3.登陆步骤

    写一个封装好的

    WxConstants把那些固定的常量封装成一个类,方便我们修改等等

    package cn.jiedada.crm.web.wechart;
    
    /*这是微信提供的必要字段
    只有通过这些方式才能获得我们所有的
    * */
    public class WxConstants {
        public  final static String APPID = "wxd853562a0548a7d0";
    
        //用户授权后微信的回调域名,当我们获得该值的时候会调用该方法
        public final static String CALLBACK="http://bugtracker.itsource.cn/callback";
    
        public final static String SCOPE = "snsapi_login";
    
        public final static String APPSECRET = "4a5d5615f93f24bdba2ba8534642dbb6";
        //微信上获取code的地址(这里的
        // appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect)
        //需要我们前台在调用的时候经行拼接REDIRECT_URI=
        public final static String CODEURL = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
        //微信上获取at的地址
        public final static String ACCESSTOKEURL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        //微信上获取用户信息的地址
        public final static String USERINFOURL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
    
    }

     因为这些都是我们必须要的字段而且不能够修改所以这样操作

    因为我们获取code,at,用户信息是在微信官方获得的所以我们需要发送请求,所以我们封装一个类来发送请求

    HttpClientUtils

    package cn.jiedada;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    
    import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    /*因为我们使用微信登陆的时候会发送请求所以要使用
    * */
    public class HttpClientUtils {
    
        /**
         * http请求工具类,post请求
         *
         * @param url    url
         * @param params json字符串的参数
         * @return
         * @throws Exception
         */
        public static String httpPost(String url, String params) throws Exception {
            // 创建httpClient对象
            DefaultHttpClient defaultHttpClient = null;
            try {
                defaultHttpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);
                httpPost.setHeader("Content-Type", "application/json;charset=ut-8");
                if (params != null) {
                    System.out.println("请求参数:" + params);
                    // 设置请求参数
                    HttpEntity httpEntity = new StringEntity(params, "utf-8");
                    httpPost.setEntity(httpEntity);
                }
                // 执行post请求,并得到相应结果
                HttpResponse httpResponse = defaultHttpClient.execute(httpPost);
                if (httpResponse.getStatusLine().getStatusCode() != 200) {
                    String errorLog = "请求失败,errorCode:" + httpResponse.getStatusLine().getStatusCode();
                    throw new Exception(url + errorLog);
                }
                // 解析结果
                HttpEntity responseEntity = httpResponse.getEntity();
                String responseStr = EntityUtils.toString(responseEntity, "utf-8");
                System.out.println("请求结果:" + responseStr);
                return responseStr;
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                throw e;
            } catch (IOException e) {
                e.printStackTrace();
                throw e;
            } finally {
                if (defaultHttpClient != null)
                    defaultHttpClient.getConnectionManager().shutdown();
            }
        }
    
        /**
         * http请求工具类,get请求
         *
         * @param url    请求地址:可以已经带参数(?),也可以没有带参数,在params中传过来
         * @param params 参数:值支持字符串和list
         * @return
         * @throws Exception
         */
        public static String httpGet(String url, Map<String, Object> params) throws Exception {
            DefaultHttpClient defaultHttpClient = null;
            try {
                defaultHttpClient = new DefaultHttpClient();
                if (params != null) {
                    // 参数的拼接
                    StringBuilder stringBuilder = new StringBuilder();
                    Iterator<String> iterator = params.keySet().iterator();
                    String key;
                    while (iterator.hasNext()) {
                        key = iterator.next();
                        Object val = params.get(key);
                        if (val instanceof List) {
                            // 如果是list,则遍历拼接
                            List v = (List) val;
                            for (Object o : v) {
                                stringBuilder.append(key).append("=").append(o.toString()).append("&");
                            }
                        } else {
                            // 字符串:直接拼接
                            stringBuilder.append(key).append("=").append(val.toString()).append("&");
                        }
                    }
                    // 删除最后一个&
                    stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                    if (url.indexOf("?") > 0) {
                        // url地址本身包含?
                        url = url + "&" + stringBuilder.toString();
                    } else {
                        url = url + "?" + stringBuilder.toString();
                    }
                }
                System.out.println("请求地址:" + url);
                HttpGet httpGet = new HttpGet(url);
                httpGet.setHeader("Content-Type", "application/json;charset=ut-8");
                // 执行
                HttpResponse httpResponse = defaultHttpClient.execute(httpGet);
                if (httpResponse.getStatusLine().getStatusCode() != 200) {
                    String errorLog = "请求失败,errorCode:" + httpResponse.getStatusLine().getStatusCode();
                    throw new Exception(url + errorLog);
                }
                // 解析结果
                HttpEntity responseEntity = httpResponse.getEntity();
                String responseStr = EntityUtils.toString(responseEntity, "utf-8");
                System.out.println("请求结果:" + responseStr);
                return responseStr;
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                throw e;
            } catch (IOException e) {
                e.printStackTrace();
                throw e;
            } finally {
                if (defaultHttpClient != null)
                    defaultHttpClient.getConnectionManager().shutdown();
            }
        }
    }
    View Code

    下面我们来获取值

    获得登陆是的二维码在登陆页面中这是后台中登陆的代码

    @RequestMapping(value = "/login",method = RequestMethod.GET)
        @ResponseBody
        public AjaxResoult wecharLogin(Model model){
            String wxLoginUrl = WxConstants.CODEURL.replaceAll("APPID", WxConstants.APPID)
                    .replaceAll("REDIRECT_URI", WxConstants.CALLBACK)
                    .replaceAll("SCOPE", WxConstants.SCOPE);
            AjaxResoult ajaxResoult = new AjaxResoult();
            ajaxResoult.setWxLoginUrl(wxLoginUrl);
            return ajaxResoult;
        }
    View Code

    前台登陆时的代码

     点击登陆

     <el-form-item>
            <el-button type="primary" @click="getWxLoginUrl">微信登陆</el-button>
          </el-form-item>
     getWxLoginUrl(event){
                    this.$http.get('/login').then((res)=>{
                        console.debug(res) ;
                        let { msg, success,wxLoginUrl, resultObj } = res.data;
                        if (!success) {
                            this.$message({
                                message: msg,
                                type: 'error'
                            });
                        } else {
                           // this.$router.push({ path: '/wxLoginUrl' });
                            window.location.href=wxLoginUrl
                        }
                    })
                },

    点击的时候发送请求

     会出现图片

    当使用手机扫码的时候会调到一个叫callback的方法中去

    这是你去官网注册获得的域名这样才能把二维码返回过来,使用回调函数

    callback方法(这里面我们需要处理的为获得at,和用户信息,判断用户是否扫过码,如果扫过就判断是否关联上了一个,如果没有就添加一个微信表的数据,并且调转到绑定页面)

     /*
        * 回调处理
        * 需要获得at
        * 和userinfo
        * */
        @RequestMapping(value = "/callback",method = RequestMethod.GET)
        public String wecharLogin(String code,String state) throws Exception {
            //获得at的url
            String atUrl = WxConstants.ACCESSTOKEURL.replaceAll("APPID", WxConstants.APPID)
                    .replaceAll("SECRET", WxConstants.APPSECRET)
                    .replaceAll("CODE", code);
            //获得at的url然后发送请求
            String atRespone = HttpClientUtils.httpGet(atUrl, null);
            System.out.println("atRespone" + atRespone);
            //因为获得user info的条件是
            // USERINFOURL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
            //需要access_token和openid
            JSONObject atParse = (JSONObject) JSON.parse(atRespone);
            System.out.println("atParse" + atParse);
            String access_token = atParse.getString("access_token");
            String openid = atParse.getString("openid");
            //获得用户信息
            String userUrl = WxConstants.USERINFOURL.replaceAll("ACCESS_TOKEN", access_token)
                    .replaceAll("OPENID", openid);
            //发送请求获得用户信息
            String userInfo = HttpClientUtils.httpGet(userUrl, null);
            System.out.println("userInfo" + userInfo);
            //转化为JSONObject对象
            JSONObject userInfoObj = (JSONObject) JSON.parse(userInfo);
            //取出其中的值
            String useropenid = userInfoObj.getString("openid");
            String nickname = userInfoObj.getString("nickname");
            String unionid = userInfoObj.getString("unionid");
            WeChart weChart = weChartService.findByopenid(useropenid);
            if (weChart == null) {
                //如果不存在就设置值进去
                WeChart weChart1 = new WeChart();
                weChart1.setOpenid(useropenid);
                weChart1.setNickname(nickname);
                weChart1.setUnionid(unionid);
                weChartService.save(weChart1);
                //跳转注册页面
                /*AjaxResoult ajaxResoult = new AjaxResoult();
                ajaxResoult.setBindUrl("redirect:/bind.jsp?openid="+useropenid);*/
                return "redirect:http://localhost:8080/#/Register?openid="+useropenid;
            } else {
                //存在直接登陆并且把数据绑定过去
                WeChart weChart2 = weChartService.findByopenid(useropenid);
                if (weChart2.getEmployee_id() != null) {
                    //通过员工id找到员工的username设置login
                    Employee employee = employeeService.findOne(weChart2.getEmployee_id());
                    //登陆当前用户
                    Subject subject = SecurityUtils.getSubject();
                    //使用自己的token
                    Map<String,Object> result = new HashMap<>();
                    //除了返回登录成功与否,还要把登录的用户返回前端
                    AjaxResoult ajaxResoult = new AjaxResoult();
                    //登录用户
                    MyUsernamePasswordToken token = new MyUsernamePasswordToken(employee.getUsername());
                    subject.login(token);
                    Serializable tokenid = subject.getSession().getId();
                    //跳转登陆页面
                    //还是返回ajaxResoult上面的自己在前台拼装就可以了
                    return "redirect:http://localhost:8080/#/echarts?tokenid="+tokenid;
                } else {
                    //跳转注册页面
                    /*AjaxResoult ajaxResoult = new AjaxResoult();
                    ajaxResoult.setBindUrl("redirect:/bind.jsp?openid="+useropenid);*/
                    return "redirect:http://localhost:8080/#/Register?openid="+useropenid;
                }
            }
        }
    View Code

    当第一次没登陆的时候我们需要跳转到登陆页面

    因为我们做了登陆权限,只能让登录页面访问,所以我们在main.js中添加了一个钩子函数

    router.beforeEach((to, from, next) => {
        if (to.path == '/login') {
            sessionStorage.removeItem('token');
        }
        //如果session没有token信息,跳转到登陆页面
        let token = sessionStorage.getItem('token');
        //获得请求栏上的地址
        let url =  window.location.href;
        //获得后台传过来的openid的值(获取http://localhost:8080/#/echarts=?tokenid如这里的tokenid)
        let openid = url.split("=")[1]; //xxx
        //判断是否放行
        if (!token && to.path != '/login') {
            //判断是否是后台穿过来的,放行注册页面
            if(openid && to.path == '/Register'){
                next();
            }
            //放行我们已经注册了的用户登陆问题
            else if(openid && to.path == '/echarts'){
                sessionStorage.setItem("token",openid);
                next();
            }
            else {
                next({ path: '/login' })
            }
        } else {
            next()
        }
    });

     这是这个页面的值这个页面

    <template>
        <div>
            <!--:model="tenant" 数据双向绑定-->
            <!--ref="tenantForm" id="tenantForm",给form去一个名字-->
            <!--:rules="formRules" 校验规则-->
            <el-form :model="employee" ref="tenantForm" :rules="formRules" label-position="left" label-width="100px" class="demo-ruleForm login-container">
                <h3 class="title">用户关联</h3>
                <el-form-item prop="companyName"label="用户名称">
                    <el-input type="text" v-model="employee.username" auto-complete="off" placeholder="请输入公司名称!"></el-input>
                </el-form-item>
                <el-form-item prop="companyNum" label="用户密码">
                    <el-input type="text" v-model="employee.password" auto-complete="off" placeholder="请输入座机!"></el-input>
                </el-form-item>
                <el-form-item style="100%;">
                    <el-button type="primary" style="100%;" @click.native.prevent="settledIn" >入驻</el-button>
                </el-form-item>
            </el-form>
        </div>
    </template>
    
    <script>
        export default {
            data() {
                //elementui提供自定义验证 value 当前这个框
                var validatePass2 = (rule, value, callback) => {
                    console.log(value); //确认密码 底层提供给我们
                    if (value === '') {
                        callback(new Error('请再次输入密码'));
                    } else if (value !== this.employee.password) {
                        callback(new Error('两次输入密码不一致!'))
                    } else {
                        callback();//表示通过
                    }
                }
                return {
                    keyword:'',
                    mapDialogVisibale:false,
                    //employee:tenant 为了做数据表单校验不要嵌套对象
                    employee: {
                        username:'',
                        password:'',
                        openid:'',
                    },
                    formRules: {
                        username: [
                            { required: true, message: '请输入用户名称!', trigger: 'blur' }
                        ],
                        password: [
                            { required: true, message: '请输入用户密码!', trigger: 'blur' }
                        ],
                        comfirmPassword: [
                            {required: true,validator: validatePass2, trigger: 'blur' } //自定义校验规则
                        ]
                    }
                };
            },
            methods: {
                selectAdrressConfirm(){
                    //把地图里面的值放入到表单地址里面,通过这种方式获得值
                    this.employee.address = document.getElementById("searchInput").value;
                    //把对话框关闭
                    this.mapDialogVisibale = false;
                },
                settledIn(){
                    //验证表单数据
                    this.$refs.tenantForm.validate((valid) => {
                        //校验表单成功后才做一下操作
                        if (valid) {
                            this.$confirm('确认关联吗?', '提示', {}).then(() => {
                                //拷贝后面对象的值到新对象,防止后面代码改动引起模型变化
                                let url =  window.location.href;
                                let openid = url.split("=")[1]; //xxx
                                let para = Object.assign({}, this.employee); //employee
                                //tenant?
                                para.openid=openid;
                                //判断是否有id有就是修改,否则就是添加
                                this.$http.post("/binder",para).then((res) =>{
                                    this.logining = false;
                                    //NProgress.done();
                                    let { msg, success, resultObj } = res.data;
    
                                    if (!success) {
                                        this.$message({
                                            message: msg,
                                            type: 'error'
                                        });
                                    } else {
                                        sessionStorage.setItem('user', JSON.stringify(resultObj.user.username));
                                        sessionStorage.setItem('token',resultObj.token);
                                        this.$router.push({ path: '/echarts' });
                                    }
                                });
                            });
                        }
                    })
                }
            },
        }
    
    </script>
    
    <style lang="scss" scoped>
        .login-container {
            -webkit-border-radius: 5px;
            border-radius: 5px;
            -moz-border-radius: 5px;
            background-clip: padding-box;
            margin: 180px auto;
             500px;
            padding: 35px 35px 15px 35px;
            background: #fff;
            border: 1px solid #eaeaea;
            box-shadow: 0 0 25px #cac6c6;
            .title {
                margin: 0px auto 40px auto;
                text-align: center;
                color: #505458;
            }
            .remember {
                margin: 0px 0px 35px 0px;
            }
        }
        .bmap{
             100%;
            height: 600px;
        }
        .searchinput{
             300px;
            box-sizing: border-box;
            padding: 9px;
            border: 1px solid #dddee1;
            line-height: 20px;
            font-size: 16px;
            height: 38px;
            color: #333;
            position: relative;
            border-radius: 4px;
        }
    </style>
    View Code

    binder方法

     /*绑定微信用户和我们的员工用户
        * */
        @RequestMapping(value = "/binder",method = RequestMethod.POST)
        @ResponseBody
        public AjaxResoult binder(@RequestBody Map<String,String> map){
            String username = map.get("username");
            System.out.println("username"+username);
            String password = map.get("password");
            System.out.println("password"+password);
            String openid = map.get("openid");
            System.out.println("openid"+openid);
            //在数据库中查找是否有该员工
            Employee employee = employeeService.findEmployeeByUsername(username);
            if(employee==null){
                return new AjaxResoult().setMsg("用户或者密码错误").setSuccess(false);
            }else {
                //判断密码是否正确
                String encrypt = MD5Util.encrypt(password);
                if(encrypt.equals(employee.getPassword())){
                    WeChart weChart = weChartService.findByopenid(openid);
                    //添加用户
                    Long employee_id = employee.getId();
                    weChart.setEmployee_id(employee_id);
                    weChartService.update(weChart);
                    AjaxResoult ajaxResoult = new AjaxResoult();
                    //登陆当前用户
                    Subject subject = SecurityUtils.getSubject();
                    //使用自己的token
                    MyUsernamePasswordToken token = new MyUsernamePasswordToken(username);
                    //登录用户
                    subject.login(token);
                    Map<String,Object> result = new HashMap<>();
                    //除了返回登录成功与否,还要把登录的用户返回前端
                    result.put("user",employee);
                    result.put("token",subject.getSession().getId());
                    ajaxResoult.setResultObj(result);
                    return ajaxResoult;
                }else {
                    return new AjaxResoult().setMsg("用户或者密码错误").setSuccess(false);
                }
            }
        }
    View Code

    这里就完成了

    但是因为我们需要使用免密登陆

    需要覆写身份认证过滤器

    FormAuthenticationFilter

    package cn.jiedada.crm.web.shiro;
    
    import cn.jiedada.crm.web.wechart.LoginType;
    import cn.jiedada.crm.web.wechart.MyUsernamePasswordToken;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
    
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * 自定义身份认证过滤器
     */
    public class MyAuthenticationFilter extends FormAuthenticationFilter {
    
        @Override
        protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
            //如果是OPTIONS请求,直接放行
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String method = httpServletRequest.getMethod();
            //判断是否是OPTIONS请求
            if("OPTIONS".equalsIgnoreCase(method)){
                return true;
            }
            return super.isAccessAllowed(request, response, mappedValue);
        }
        //薪增方法
        @Override
        protected AuthenticationToken createToken(String username, String password, ServletRequest request, ServletResponse response) {
            boolean rememberMe = isRememberMe(request);
            String host = getHost(request);
            String loginType = LoginType.PASSWORD;//需要密码
    
            if(request.getParameter("loginType")!=null && !"".equals(request.getParameter("loginType").trim())){
                loginType = request.getParameter("loginType");
            }
    
            return new MyUsernamePasswordToken(username, password,loginType,rememberMe,host);
        }
    }
    View Code

    所以需要覆写他的加密验证方法

    HashedCredentialsMatcher

    package cn.jiedada.crm.web.wechart;
    
    import com.sun.org.apache.xml.internal.resolver.readers.DOMCatalogReader;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    
    public class MyHashedCredentialsMatcher extends HashedCredentialsMatcher {
        //doCredentialsMatch
    
        @Override
        public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
            //使用我们自定义的MyUsernamePasswordToken
            MyUsernamePasswordToken mupt = (MyUsernamePasswordToken) token;
            //是否是免密登陆,最后修改配置
            if (mupt.getLoginType().equals(LoginType.NOPASSWD)) {
                //免密登录
                return true;
            }
            return super.doCredentialsMatch(token, info);
        }
    }
    View Code

    而其中需要使用覆写

    UsernamePasswordToken

    package cn.jiedada.crm.web.wechart;
    
    import com.sun.org.apache.xml.internal.resolver.readers.DOMCatalogReader;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    
    public class MyHashedCredentialsMatcher extends HashedCredentialsMatcher {
        //doCredentialsMatch
    
        @Override
        public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
            //使用我们自定义的MyUsernamePasswordToken
            MyUsernamePasswordToken mupt = (MyUsernamePasswordToken) token;
            //是否是免密登陆,最后修改配置
            if (mupt.getLoginType().equals(LoginType.NOPASSWD)) {
                //免密登录
                return true;
            }
            return super.doCredentialsMatch(token, info);
        }
    }
    View Code

    而UsernamePasswordToken需要一个常量类

    package cn.jiedada.crm.web.wechart;
    
    public class LoginType {
        public static final String NOPASSWD = "NoPassword";
        public static final String PASSWORD = "Password";
    }
    View Code

    并且配置到shiro中

    在application-shiro.xml中配置这里是所有的配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
    
        <!--session管理器通过继承DefaultWebSecurityManager来自定义我们的session-->
        <bean id="crmSessionManager" class="cn.jiedada.crm.web.shiro.CrmSessionManager"></bean>
        <!--shiro的核心对象-->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <!--配置realm-->
            <property name="sessionManager" ref="crmSessionManager"/>
            <property name="realm" ref="myRealm"/>
        </bean>
    
    
        <!--Realms-->
        <bean id="myRealm" class="cn.jiedada.crm.web.shiro.MyRealm">
            <property name="credentialsMatcher">
                <bean class="cn.jiedada.crm.web.wechart.MyHashedCredentialsMatcher">
                    <property name="hashAlgorithmName" value="MD5"/>
                    <property name="hashIterations" value="10"/>
                </bean>
            </property>
        </bean>
        <!--自定义过滤器-->
        <bean id="myAuthenticationFilter" class="cn.jiedada.crm.web.shiro.MyAuthenticationFilter"></bean>
        <bean id="aisellPermissionsAuthorizationFilter" class="cn.jiedada.crm.web.shiro.AisellPermissionsAuthorizationFilter"></bean>
        <!--shiro的过滤器配置-->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <property name="loginUrl" value="/login"/>
            <property name="successUrl" value="/s/index"/>
            <property name="unauthorizedUrl" value="/s/unauthorized"/>
            <!--通过key在下面找到我们需要的东西,需要使用value-ref关联-->
            <property name="filters">
                <map>
                    <entry key="myFilter" value-ref="myAuthenticationFilter"></entry>
                    <entry key="aisellPers" value-ref="aisellPermissionsAuthorizationFilter"></entry>
                </map>
            </property>
            <!--在这下面使用我们的myFilter-->
            <!--<property name="filterChainDefinitions">
                <value>
                    /* = anon
                    /js/** = anon
                    /** = myFilter
                </value>
            </property>-->
        </bean>
        <bean id="filterChainDefinitionMap" factory-bean="shiroFilterMapFactory" factory-method="createMap" />
        <!--配置返回shiro权限拦截的bean-->
        <bean id="shiroFilterMapFactory" class="cn.jiedada.crm.web.shiro.ShiroFilterMapFactory"/>
    
    
    </beans>
    View Code
  • 相关阅读:
    LL(1)文法的判断,递归下降分析程序
    消除左递归
    DFA最小化,语法分析初步
    非确定的自动机NFA确定化为DFA
    正规式、正规文法与自动机
    第03组 Alpha事后诸葛亮
    第03组 Alpha冲刺(4/4)
    第03组 Alpha冲刺(3/4)
    第03组 Alpha冲刺(2/4)
    第03组 Alpha冲刺(1/4)
  • 原文地址:https://www.cnblogs.com/xiaoruirui/p/11877777.html
Copyright © 2020-2023  润新知