美文网首页
shiro自定义登录校验

shiro自定义登录校验

作者: TheRaging | 来源:发表于2020-11-16 14:11 被阅读0次

    Controller层

    //这个方法主要储存自定义生成的TOKEN 
     @RequestMapping(value = "/login",method = {RequestMethod.GET})
        public  RspMsg Login(User user){
            Subject subject = SecurityUtils.getSubject();
            //UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken();
            //生成自己的Token
            user.setUser_phone("17637945521");
            user.setUser_name("123");
            user.setOpenid("123456openid");
         //使用了JWT用于生成token  也可以自定义验证的信息以及session里储存的信息 
            String token = jwt.createToken(user);
            MyToken myToken = new MyToken(token);
    //传入用户信息实体类
            subject.login(myToken);
            System.out.println("登录成功");
    //      获取登录成功后的subject的内容
      System.out.println(subject.getPrincipal());
            return RspMsg.Success(myToken);
        }
    

    自定义自己的用户信息实体类

    package com.eat.entity;
    
    import org.apache.shiro.authc.AuthenticationToken;
    
    /**
     * @version V1.0
     * @Package com.eat.entity
     * @ClassName Token
     * @Description 自定义Token类
     * @Author 王振鹏
     * @date 2020/10/26 21:47
     **/
    public class MyToken implements AuthenticationToken {
    
    //UsernamePasswordToken 的属性
    // getUsername 账户,账号
    // getPassword 密码
    // getPrincipal 身份 
    // getCredentials 加密凭据
    // getHost 主机地址
    // isRememberMe 是否记住账号密码
        private String Token;
    
        public MyToken(String token){
            System.out.println("tokern------------------------");
            System.out.println(token);
            this.Token = token;
        }
    
        @Override
        public  String getPrincipal() {
            return Token;
        }
    
        @Override
        public Object getCredentials() {
            return Token;
        }
    }
    

    自定义的Relam

    package com.eat.config;
    
    import com.eat.entity.User;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @version V1.0
     * @Package com.eat.config
     * @ClassName MyRealm
     * @Description TODO
     * @Author 王振鹏
     * @date 2020/10/23 23:10
     **/
    @Configuration
    public class MyRealm extends AuthorizingRealm {
    
    
    
        /**
         * @Summary
         * @Param: [principals]
         * @Return: org.apache.shiro.authz.AuthorizationInfo
         * @Author: TheRaging
         * @Date: 2020/10/23 23:13
         * @Description 授权方法,获取角色,权限信息
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    
            System.out.println("权限校验");
            return null;
        }
    
        /**
         * @Summary
         * @Param: [token]
         * @Return: org.apache.shiro.authc.AuthenticationInfo
         * @Author: TheRaging
         * @Date: 2020/10/23 23:13
         * @Description 身份信息,获取账号信息,进行密码认证,
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("进入到登录方法doGetAuthenticationInfo---------------------------");
            //校验token是否为空
            if (StringUtils.isEmpty(token.getPrincipal().toString())) {
                return null;
            }
    
            //获取用户信息
           /* User creatUser = JSONObject.parseObject(jwt.verifyTokenObject(token.getPrincipal().toString()).toString(),User.class);
            User user   = userService.SelectUserByUserName(creatUser.getUser_name());
            System.out.println(creatUser.toString());
            System.out.println(user);
            //System.out.println("getresult------------------------------");
            //System.out.println(r.getResult());
            System.out.println(user.getUser_name());
            if(user==null){
                return  null;
            }*/
    
                //这里验证authenticationToken和simpleAuthenticationInfo的信
                //SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user,"密码",getName());
            System.out.println(token.getPrincipal().toString());
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(),getName());
                return simpleAuthenticationInfo;
    
        }
        /**
         * 此方法必须重写,只有重写了才可以使用自己的token
           具体原因,目前也还不太清楚,
         */
        @Override
        public boolean supports(AuthenticationToken token) {
            System.out.println("supports---------------------------------");
           // System.out.println(token);
            return   true;
        }
    
        /**
         * 如果需要用shiro缓存授权信息,每次请求都会走AuthorizingRealm中的getAuthorizationInfo方法,如果配置了使用了缓存,
         * 这两句代码(Object key = getAuthorizationCacheKey(principals); info = cache.get(key);)会首先从缓存
         * 中取授权信息,因为用了spring session,默认的取缓存的方法是得到之前登录成功的PrincipalCollection principals,
         * 但是因为每次都是从spring session表中去反序列化得到此对象,所以每次的对象都是新的,
         * 导致每次从缓存中取都取不到,现在重写此方法,将key改成每次登录后的登录名称,类型是String,这样cache.get(key)
         * 时,比较的是String的equals方法,则只要登录名称不变就能取到缓存中的值。
         *
         * @param principals 登录成功的凭证(user信息)
         * @return 从
         */
        @Override
        protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
            User userInfo = (User) principals.getPrimaryPrincipal();
            System.out.println("getAuthorizationCacheKey===============================================");
            return userInfo.getOpenid();
        }
    }
    

    自定义密码验证

    package com.eat.config;
    
    import com.alibaba.fastjson.JSONObject;
    import com.eat.util.integer.JWT;
    import com.eat.entity.User;
    import com.eat.service.UserService;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.credential.CredentialsMatcher;
    import org.springframework.beans.factory.annotation.Autowired;
    
    /**
     * @version V1.0
     * @Package com.eat.config
     * @ClassName MyCredentialsMatcher
     * @Description TODO
     * @Author 王振鹏
     * @date 2020/10/23 23:49
     **/
    public class MyCredentialsMatcher implements CredentialsMatcher {
    
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private JWT jwt;
    
    
        /**
         * @Summary
         * @Param: [token, info]
         * @Return: boolean
         * @Author: TheRaging
         * @Date: 2020/10/23 23:49
         * @Description 密码校验器,在这里实现自定义的密码校验
         */
        //@Override
        public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
    
            System.out.println("密码校验doCredentialsMatch------------------------------");
            //System.out.println("token------------"+token.getPrincipal());
            //System.out.println(token.getCredentials());
            //System.out.println("info---------------------"+info);
            User creatUser = JSONObject.parseObject(jwt.verifyTokenObject(token.getPrincipal().toString()).toString(),User.class);
            User user   = userService.SelectUserByUserName(creatUser.getUser_name());
            System.out.println(user.getUser_img());
            //System.out.println(user.toString());
            //System.out.println(creatUser.toString());
            if(user == null){
                System.out.println("没有此用户");
                return  false;
            }
            if(user.getUser_name().equals(creatUser.getUser_name()) && user.getOpenid().equals(creatUser.getOpenid())){
                System.out.println("登录成功");
                return true;
            }else{
                System.out.println("账号或密码不正确");
                return  false;
            }
            /*  UsernamePasswordToken utoken=(UsernamePasswordToken) token;
            //获得用户输入的密码:(可以采用加盐(salt)的方式去检验)
            String inPassword = new String(utoken.getPassword());
            String username = utoken.getUsername();
            //获得数据库中的密码
            String dbPassword = (String) info.getCredentials();
            SimpleAuthenticationInfo saInfo = (SimpleAuthenticationInfo)info;
            String salt = userService.findUserByName(username).getSalt();
            inPassword = CommunityUtil.md5(inPassword+salt);
            //进行密码的比对
            boolean flag = Objects.equals(inPassword, dbPassword);
            return flag;*/
        }
    }
    

    JWT生成TOKEN工具类

    package com.eat.util;
    
    
    
    import com.eat.util.integer.JWT;
    import org.jose4j.json.JsonUtil;
    import org.jose4j.jwk.RsaJsonWebKey;
    import org.jose4j.jwk.RsaJwkGenerator;
    import org.jose4j.jws.AlgorithmIdentifiers;
    import org.jose4j.jws.JsonWebSignature;
    import org.jose4j.jwt.JwtClaims;
    import org.jose4j.jwt.NumericDate;
    import org.jose4j.jwt.consumer.InvalidJwtException;
    import org.jose4j.jwt.consumer.JwtConsumer;
    import org.jose4j.jwt.consumer.JwtConsumerBuilder;
    import org.jose4j.lang.JoseException;
    import org.springframework.stereotype.Component;
    
    import java.security.PrivateKey;
    import java.security.SecureRandom;
    import java.util.UUID;
    
    /**
     * @version V1.0
     * @Package com.eat.comom.util
     * @ClassName JWTUtils
     * @Description TODO
     * @Author 王振鹏
     * @date 2020/10/19 22:40
     **/
    @Component
    public class JWTUtils implements JWT {
        /**
         * keyId,公钥,私钥 都是用 createKeyPair 方法生成
         */
        private static String keyId = null;
        private static String privateKeyStr = null;
        private static String publicKeyStr = null;
        public static long accessTokenExpirationTime = 60 * 60 * 24;
    
        //jws创建token
        public String createToken(Object account) {
           //调用方法生成keyId,公钥,私钥
            createKeyPair();
            try {
                //Payload
                JwtClaims claims = new JwtClaims();
                claims.setGeneratedJwtId();
                claims.setIssuedAtToNow();
                //expire time
                NumericDate date = NumericDate.now();
                date.addSeconds(accessTokenExpirationTime);
                claims.setExpirationTime(date);
                claims.setNotBeforeMinutesInThePast(1);
                claims.setSubject("YOUR_SUBJECT");
                claims.setAudience("YOUR_AUDIENCE");
                //添加自定义参数,必须是字符串类型
                claims.setClaim("account", account);
    
                //jws
                JsonWebSignature jws = new JsonWebSignature();
                //签名算法RS256
                jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
                jws.setKeyIdHeaderValue(keyId);
                jws.setPayload(claims.toJson());
                /*
                RsaJsonWebKey jwk = null;
                try {
                    jwk = RsaJwkGenerator.generateJwk(2048);
                    } catch (JoseException e) {
                        e.printStackTrace();
                    }
                    jwk.setKeyId(keyId); */
                //PrivateKey privateKey = jwk.getPrivateKey();
                PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyStr)).getPrivateKey();
                jws.setKey(privateKey);
    
                //get token
                String idToken = jws.getCompactSerialization();
                return idToken;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //jws创建token
        public String createToken(String account,String SUBJECT) {
            //调用方法生成keyId,公钥,私钥
            createKeyPair();
            try {
                //Payload
                JwtClaims claims = new JwtClaims();
                claims.setGeneratedJwtId();
                claims.setIssuedAtToNow();
                //expire time
                NumericDate date = NumericDate.now();
                date.addSeconds(accessTokenExpirationTime);
                claims.setExpirationTime(date);
                claims.setNotBeforeMinutesInThePast(1);
                claims.setSubject(SUBJECT);
                claims.setAudience("YOUR_AUDIENCE");
                //添加自定义参数,必须是字符串类型
                claims.setClaim("account", account);
    
                //jws
                JsonWebSignature jws = new JsonWebSignature();
                //签名算法RS256
                jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
                jws.setKeyIdHeaderValue(keyId);
                jws.setPayload(claims.toJson());
                /*
                RsaJsonWebKey jwk = null;
                try {
                    jwk = RsaJwkGenerator.generateJwk(2048);
                    } catch (JoseException e) {
                        e.printStackTrace();
                    }
                    jwk.setKeyId(keyId); */
                //PrivateKey privateKey = jwk.getPrivateKey();
                PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyStr)).getPrivateKey();
                jws.setKey(privateKey);
    
                //get token
                String idToken = jws.getCompactSerialization();
                return idToken;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //jws创建token
        public String createToken(String account,String SUBJECT,String AUDIENCE) {
            //调用方法生成keyId,公钥,私钥
            createKeyPair();
            try {
                //Payload
                JwtClaims claims = new JwtClaims();
                claims.setGeneratedJwtId();
                claims.setIssuedAtToNow();
                //expire time
                NumericDate date = NumericDate.now();
                date.addSeconds(accessTokenExpirationTime);
                claims.setExpirationTime(date);
                claims.setNotBeforeMinutesInThePast(1);
                claims.setSubject(SUBJECT);
                claims.setAudience(AUDIENCE);
                //添加自定义参数,必须是字符串类型
                claims.setClaim("account", account);
    
                //jws
                JsonWebSignature jws = new JsonWebSignature();
                //签名算法RS256
                jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
                jws.setKeyIdHeaderValue(keyId);
                jws.setPayload(claims.toJson());
                /*
                RsaJsonWebKey jwk = null;
                try {
                    jwk = RsaJwkGenerator.generateJwk(2048);
                    } catch (JoseException e) {
                        e.printStackTrace();
                    }
                    jwk.setKeyId(keyId); */
                //PrivateKey privateKey = jwk.getPrivateKey();
                PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyStr)).getPrivateKey();
                jws.setKey(privateKey);
    
                //get token
                String idToken = jws.getCompactSerialization();
                return idToken;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * jws校验token
         *
         * @param token
         * @return 返回 用户账号
         * @throws JoseException
         */
        public boolean verifyTokenBoolean(String token) {
            try {
                JwtConsumer consumer = new JwtConsumerBuilder()
                        .setRequireExpirationTime()
                        .setMaxFutureValidityInMinutes(5256000)
                        .setAllowedClockSkewInSeconds(30)
                        .setRequireSubject()
                        //.setExpectedIssuer("")
                        .setExpectedAudience("YOUR_AUDIENCE")
                        /*
                        RsaJsonWebKey jwk = null;
                        try {
                            jwk = RsaJwkGenerator.generateJwk(2048);
                            } catch (JoseException e) {
                                e.printStackTrace();
                            }
                            jwk.setKeyId(keyId); */
                        //.setVerificationKey(jwk.getPublicKey())
                        .setVerificationKey(new RsaJsonWebKey(JsonUtil.parseJson(publicKeyStr)).getPublicKey())
                        .build();
                //System.out.println("11111111111111111111111");
                JwtClaims claims = consumer.processToClaims(token);
               // System.out.println("~~~~~~~~~~~~~~~~~~~"+claims);
                if (claims != null||!claims.equals("") ) {
                    //System.out.println("认证通过!");
                    //System.out.println(claims);
                    String account = (String) claims.getClaimValue("account");
                    //System.out.println("token payload携带的自定义内容:用户账号account=" + account);
                    return true;
                }else {
                    //System.out.println("认证失败!");
    
                    return false;
                }
            }  catch (JoseException e) {
                e.printStackTrace();
            }  catch (InvalidJwtException e) {
                e.printStackTrace();
            }catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }
    
        public Object verifyTokenObject(String token){
            try {
                JwtConsumer consumer = new JwtConsumerBuilder()
                        .setRequireExpirationTime()
                        .setMaxFutureValidityInMinutes(5256000)
                        .setAllowedClockSkewInSeconds(30)
                        .setRequireSubject()
                        //.setExpectedIssuer("")
                        .setExpectedAudience("YOUR_AUDIENCE")
                        /*
                        RsaJsonWebKey jwk = null;
                        try {
                            jwk = RsaJwkGenerator.generateJwk(2048);
                            } catch (JoseException e) {
                                e.printStackTrace();
                            }
                            jwk.setKeyId(keyId); */
                        //.setVerificationKey(jwk.getPublicKey())
                        .setVerificationKey(new RsaJsonWebKey(JsonUtil.parseJson(publicKeyStr)).getPublicKey())
                        .build();
                //System.out.println("11111111111111111111111");
                JwtClaims claims = consumer.processToClaims(token);
                // System.out.println("~~~~~~~~~~~~~~~~~~~"+claims);
                if (claims != null||!claims.equals("") ) {
                    //System.out.println("认证通过!");
                    //System.out.println(claims);
                    Object account =  claims.getClaimValue("account");
                    //System.out.println("token payload携带的自定义内容:用户账号account=" + account);
                    return account;
                }else {
                    //System.out.println("认证失败!");
    
                    return null;
                }
            }  catch (JoseException e) {
                e.printStackTrace();
            }  catch (InvalidJwtException e) {
                e.printStackTrace();
            }catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
        /**
         * 创建jwk keyId , 公钥 ,秘钥
         */
        public static void createKeyPair(){
            /**
             * UUID.randomUUID().toString()是javaJDK提供的一个自动生成主键的方法。
             * UUID(Universally Unique Identifier)全局唯一标识符,
             * 是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,
             * 是由一个十六位的数字组成,表现出来的 形式。由以下几部分的组合:
             * 当前日期和时间(UUID的第一个部分与时间有关,
             * 如果你在生成一个UUID之后,过几秒又生成一个UUID,
             * 则第一个部分不 同,其余相同),时钟序列,全局唯一的IEEE机器识别号
             * (如果有网卡,从网卡获得,没有网卡以其他方式获得),
             * UUID的唯一缺陷在于生成的结果串会比较长。
             * UUID是由一个十六位的数字组成,表现出来的形式例如 550E8400-E29B-11D4-A716-446655440000
             * String uid = UUID.randomUUID().toString().substring(0,5);
             * //六位UUID
             * //bf7c30
             */
            keyId = UUID.randomUUID().toString().replaceAll("-", "");
            RsaJsonWebKey jwk = null;
            try {
                SecureRandom s = new SecureRandom();
                jwk = RsaJwkGenerator.generateJwk(2048);
            } catch (JoseException e) {
                e.printStackTrace();
            }
            jwk.setKeyId(keyId);
            //采用的签名算法 RS256
            jwk.setAlgorithm(AlgorithmIdentifiers.RSA_USING_SHA256);
            publicKeyStr = jwk.toJson(RsaJsonWebKey.OutputControlLevel.PUBLIC_ONLY);
            privateKeyStr = jwk.toJson(RsaJsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
    
            //System.out.println("keyId="+keyId);
           // System.out.println();
           // System.out.println("公钥 publicKeyStr="+publicKey);
           // System.out.println();
           // System.out.println("私钥 privateKeyStr="+privateKey);
    
        }
        /*public static void main(String[] args) {
            JWTUtils s = new JWTUtils();
            System.out.println("------------");
            String a = s.createToken("你好啊,王振鹏");
            System.out.println(a);
            System.out.println("------------2");
            String b = s.verifyToken(a);
            System.out.println(b);
            System.out.println("============================");
            //System.out.println(s.verifyToken("eyJhbGciOiJSUzI1NiIsImtpZCI6ImZhNjc3ZDUyNWMwZTRlZTQ4NWE2MTU0MzkzNzc5NGFmIn0.eyJqdGkiOiJyc3A0UEEybFZRSUNEb1VEWlVXVU1BIiwiaWF0IjoxNjAzMjA5NzMzLCJleHAiOjE2MDMyOTYxMzMsIm5iZiI6MTYwMzIwOTY3Mywic3ViIjoiWU9VUl9TVUJKRUNUIiwiYXVkIjoiWU9VUl9BVURJRU5DRSIsImFjY291bnQiOiLkvaDlpb3llYrvvIznjovmjK_puY8ifQ.KueqUX6FeYJ-WNotAZh9nvyeb0xjLfYPNbmQR2CbJYaiOuBkeI65Fc53n_FDfJINY3NVUNIkBAb5M4zvzPdORIhsceI3nef0-vfuH6CC-9w1bZqtY9qZ42FUSDgBocZlsLZDFM5jLr2WR3gPCZg7urhdGZNwfkBhGB3gYvUbntOLcWBqpRSqtfVqMPXGSxGx671CaELCO58Bgxl5QSjWi-yhbjcUS9SV4oD248DKtIemBLFV5YhE7uEqxCIFlqXLcIVCTFuQmv9DEmZidSk0cDYuYAPMEc8cVSxZmvb8nZlRwfWgBsj-E-5v3F6ofY9BBxaPesQcLQ_onxZBZ3IS_w1"));
        }*/
    }
    

    shiro的配置文件

    package com.eat.config;
    
    
    
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.session.mgt.SessionManager;
    import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
    import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.servlet.Filter;
    import java.util.HashMap;
    import java.util.Map;
    /**
     * @version V1.0
     * @Package com.eat.config
     * @ClassName ShiroConfig
     * @Description TODO
     * @Author 王振鹏
     * @date 2020/10/23 22:22
     **/
    @Configuration
    public class ShiroConfig {
    
        /**
         * @Summary
         * @Param: []
         * @Return: CustomRealm
         * @Author: TheRaging
         * @Date: 2020/10/23 22:28
         * @Description 配置ShiroRealm用于登录验证逻辑,返回自定义的ShiroRealm 相当于一个数据源
         * 身份验证(getAuthenticationInfo 方法)验证账户和密码,并返回相关信息
         * 权限获取(getAuthorizationInfo 方法) 获取指定身份的权限,并返回相关信息
         * 令牌支持(supports方法)判断该令牌(Token)是否被支持
         */
        @Bean
        public MyRealm myShiroRealm() {
            MyRealm customRealm = new MyRealm();
            //自定义密码验证
            customRealm.setCredentialsMatcher(myCredentialsMatcher());
            return customRealm;
        }
    
        /**
         * @Summary
         * @Param: []
         * @Return: java.lang.SecurityManager
         * @Author: TheRaging
         * @Date: 2020/10/23 22:29
         * @Description 配置SecurityManager,用于管理认证
         */
        @Bean
        public SecurityManager securityManager() {
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            securityManager.setRealm(myShiroRealm());
            //设置自定义的session管理器
            securityManager.setSessionManager(sessionManager());
            return securityManager;
        }
    
        /**
         * @Summary
         * @Param: [securityManager]
         * @Return: ShiroFilterFactoryBean
         * @Author: TheRaging
         * @Date: 2020/10/23 22:30
         * @Description 配置ShiroFilterFactoryBean过滤器,用于过滤url地址,然后决定哪些路径需要认证
         */
        @Bean
        public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            //设置使用自定义的filter进行过滤
            Map<String, Filter> filters = new HashMap<>();
            filters.put("filter", new MyFilter());
            //配置自定义的过滤规则
            shiroFilterFactoryBean.setFilters(filters);
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            Map<String, String> map = new HashMap<>();
            //登录
            map.put("/test/login", "anon");
            //登出
            map.put("/logout", "logout");
            //登录失败跳转的页面
           // shiroFilterFactoryBean.setLoginUrl("/test/login");
            //配置登录成功的跳转页面,默认跳转到/
            //shiroFilterFactoryBean.setSuccessUrl("/index");
            //没有权限,权限校验失败跳转的页面
            //shiroFilterFactoryBean.setUnauthorizedUrl("/error");
            //对所有用户认证
            map.put("/**", "filter");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
            return shiroFilterFactoryBean;
        }
    
        /**
         * shiro缓存管理器
         * 1 添加相关的maven支持
         * 2 注册这个bean,将缓存的配置文件导入
         * 3 在securityManager 中注册缓存管理器,之后就不会每次都会去查询数据库了,相关的权限和角色会保存在缓存中,但需要注意一点,更新了权限等操作之后,需要及时的清理缓存
         */
       /* @Bean
        public EhCacheManager ehCacheManager() {
            EhCacheManager cacheManager = new EhCacheManager();
            cacheManager.setCacheManagerConfigFile("classpath:config/ehcache.xml");
            return cacheManager;
        }*/
    
    
        /**
         * 自定义的 shiro session 缓存管理器,用于跨域等情况下使用 token 进行验证,不依赖于sessionId
         * @return
         */
        @Bean
        public SessionManager sessionManager(){
            //将我们继承后重写的shiro session 注册
            MySession shiroSession = new MySession();
            //如果后续考虑多tomcat部署应用,可以使用shiro-redis开源插件来做session 的控制,或者nginx 的负载均衡
            shiroSession.setSessionDAO(new EnterpriseCacheSessionDAO());
            return shiroSession;
        }
    
        /**
         * @Summary
         * @Param: []
         * @Return: MyCredentialsMatcher
         * @Author: TheRaging
         * @Date: 2020/10/23 23:45
         * @Description 配置自定义的密码校验类MyCredentialsMatcher
         * MyCredentialsMatcher 需要继承CredentialsMatcher 实现重写
         * 但是同时需要在SecurityManager中设置
         * SecurityManager.setCredentialsMatcher(myCredentialsMatcher());
         */
        @Bean
        public MyCredentialsMatcher myCredentialsMatcher() {
            return new MyCredentialsMatcher();
        }
    
    
        /**
         * @Summary
         * @Param: []
         * @Return: org.apache.shiro.mgt.SecurityManager
         * @Author: TheRaging
         * @Date: 2020/10/23 23:51
         * @Description 配置实现自定义的securityManager
         * MySessionManager需要继承 DefaultWebSessionManager 实现重写
         * 但是同时也需要在 securityManager 中添加
         * SecurityManager.setSessionManager(sessionManager());
         */
      /*  @Bean
        public SessionManager sessionManager(){
            MySessionManager mySessionManager = new MySessionManager();
            //这里可以不设置。Shiro有默认的session管理。如果缓存为Redis则需改用Redis的管理
            mySessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
            return mySessionManager;
        }*/
    
    
    
        //DefaultAdvisorAutoProxyCreator 和AuthorizationAttributeSourceAdvisor两个在一起才能支Shiro的注解权限控制实现
        /**
         * @Summary
         * @Param: []
         * @Return: org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
         * @Author: TheRaging
         * @Date: 2020/10/23 22:33
         * @Description  配置,这个是AOP的,相当于一个切面
         *  他会扫描所有的类中的Advisor,
         *  然后这些Advisor应用到所有符合切入点的Bean中
         */
        @Bean
        @ConditionalOnMissingBean
        public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
            DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
            defaultAAP.setProxyTargetClass(true);
            return defaultAAP;
        }
    
        /**
         * @Summary
         * @Param: [securityManager]
         * @Return: AuthorizationAttributeSourceAdvisor
         * @Author: TheRaging
         * @Date: 2020/10/23 22:38
         * @Description 配置 aop  这个类就相当于切点了
         */
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:shiro自定义登录校验

          本文链接:https://www.haomeiwen.com/subject/eigabktx.html