Springboot 整合shiro

         今天加班,事情做的差不多,先前对Springboot 整合 shiro 有稍微研究一下下,但项目搭建好后,都是一直的复用复用,时间一长,都忘记整合流程了,网上Springboot 整合 shiro 教程也有很多,我呢,也没有什么太大的特色,就想搞个由浅入深,从初级整合到进阶版,增加redis作为缓存,一步一步来,方便学习也方便自己记忆。

       首先,我们要整合是初级版,只有 Springboot 整合 shiro,步骤如下:

  • 初级版:

第一步:导包:

  如果一切都从 Hello World 开始,整合也都是从 pom.xml 文件中引入 shiro的jar包

		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.4.0</version>
		</dependency>

第二步:编写 shiro 自定义认证类 Realm

在自定义的Realm 中,根据实际业务,完善相应的密码校验和鉴权授权代码

import com.workbench.sys.SysAccount;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
 * 自定义shiro验证
 * @Auther: He
 * @Create_Date: 2020/8/30 10:55
 */
public class MyShiroRealm extends AuthorizingRealm {


    /**
     * 对登录账号进行鉴权授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println(">>>> 鉴权授权 <<<<");
        //获取登录用户名
        String account = (String) principalCollection.getPrimaryPrincipal();
        //根据用户名去数据库查询用户信息
//        SysAccount sysAccount = iSysAccountService.selectSysAccountInfoByAccount(account);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//        for (Role role : user.getRoles()) {
//            //添加角色
//            simpleAuthorizationInfo.addRole(role.getRoleName());
//            //添加权限
//            for (Permissions permissions : role.getPermissions()) {
//                simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
//            }
//        }
        return simpleAuthorizationInfo;
    }

    /**
     * 校验登录账户是否正确
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println(">>>>> 登录认证 <<<<<");
        //加这一步的目的是在Post请求的时候会先进认证,然后在到请求
        if (authenticationToken.getPrincipal() == null) {
            return null;
        }
        //获取用户信息
        String account = authenticationToken.getPrincipal().toString();
        //模拟数据库查询
        SysAccount sysAccount = new SysAccount();
        sysAccount.setAccount("abc");
        sysAccount.setPassword("123");
        if (sysAccount == null) {
            //这里返回后会报出对应异常
            return null;
        } else {
            //这里验证authenticationToken和simpleAuthenticationInfo的信息
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(account, sysAccount.getPassword().toString(), getName());
            return simpleAuthenticationInfo;
        }
    }

    /**
     * RealmSecurityManager rsm = (RealmSecurityManager)SecurityUtils.getSecurityManager();
     AuthRealm authRealm = (AuthRealm)rsm.getRealms().iterator().next();
     authRealm.clearAuthz();
     */
    public void clearAuthor(){
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

    public void clearAuthen(){
        this.clearCachedAuthenticationInfo(SecurityUtils.getSubject().getPrincipals());
    }
}

第三步:编写配置类 ShiroConfig

 Shiro 配置类中设置相应的拦截规则,并添加注册自定义的验证类

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.*;

/**
 * Shiro 配置类
 * @Auther: He
 * @Create_Date: 2020/8/30 10:59
 */
@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //拦截器.
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 按顺序判断
        //登录
        filterChainDefinitionMap.put("/sys/login", "anon");
        filterChainDefinitionMap.put("/staff/auth/mobileCode", "anon");
        filterChainDefinitionMap.put("/staff/auth/forgetPassword", "anon");
        filterChainDefinitionMap.put("/sys/attachment/upload", "anon");
        filterChainDefinitionMap.put("/sys/attachment/selectImg", "anon");


        //authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
        filterChainDefinitionMap.put("/**", "authc,perms");
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //未授权界面;
//		shiroFilterFactoryBean.setUnauthorizedUrl("/403");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 凭证匹配器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
     * )
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        return hashedCredentialsMatcher;
    }

    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }

    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

}

设置拦截规则时,切记要把 登录请求设置成 anon ,即免登陆访问

如:filterChainDefinitionMap.put("/sys/login", "anon");

第四步:编写controller类进行校验

/**
     * 登录方法
     * @param request
     * @param sysAccount
     * @return
     */
    @RequestMapping(value = "/login")
    public Result<SysAccount> login(HttpServletRequest request, @RequestBody SysAccount sysAccount) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(sysAccount.getAccount(), sysAccount.getPassword());
        subject.login(usernamePasswordToken);
        Session session = SecurityUtils.getSubject().getSession();
        return getResult(Result.OK, session);
    }

接下来就是使用 Postman 等工具进行测试了。

至此,初级版的 Springboot 整合 Shiro 就完成了。

进阶版的后面更新

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 我是一条华丽的分割线 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值