shiro自定义登录校验

2020-11-16  本文已影响0人  TheRaging

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;
    }

}

上一篇下一篇

猜你喜欢

热点阅读