SpringBoot整合shrio、mysql

首先是新建一个springboot项目,把依赖装好

然后把mybatis整合进项目中,这里便不多赘述

装好后便可以开始整合这个安全框架了

首先在配置之前,我们需要明确shrio的三大对象

  • Subject 用户
  • SecurityManager 管理所有用户
  • Realm 连接数据

这三个对象贯穿整个项目的整合

1.导包

 <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.8.0</version>
        </dependency>

2.编写配置类

@Configuration
public class ShiroConfig {
    //ShrioFilterFactoryBean
    //DefaultWebSecurityManager
    //创建realm对象,需要自定义类
    
}

我们分别把通过这三个类将shrio的核心三个对象声明出来,再对其中他们的属性进行一个设置就行

2.1创建realm对象

public class SelfRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        return null;
    }
}

这个类继承 AuthorizingRealm

每次进行登录时都会首先运行这个realm对象 

 2.2创建shrio三个核心对象

我们需要在shrio配置类中进行建立

@Configuration
public class ShiroConfig {
    //ShiroFilterFactoryBean
    public ShiroFilterFactoryBean getShrioFilterFactoryBean(@Qualifier("SecurityManager") DefaultWebSecurityManager defaultWebSecurityManager)
    {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        return shiroFilterFactoryBean;
    }
    //DefaultWebSecurityManager
    @Bean(name = "SecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("myrealm") MyRealm myrealm)
    {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(myrealm);
        return defaultWebSecurityManager;
    }
    //创建realm对象,需要自定义类
    @Bean(name = "myrealm")
    public MyRealm getMyRealm()
    {
        return new MyRealm();
    }
}

 配置过程中是从最后的一个realm对象创建起,这样逻辑才能顺畅些。至此shrio的基本框架就搭建完成了,接下来是对权限以及认证的一个操作。

3.操作权限与认证

3.1 登录拦截

在getShrioFilterFactoryBean方法中实现拦截功能

加入以下代码

//添加shrio内置过滤器
/*
* anon:无需认证便可访问
* authc:必须认证才能访问
* user:必须拥有记住我才能使用
* perms:拥有对某个资源才能访问
* role:拥有某个角色
* */
Map linkedMap = new LinkedHashMap<String,Object>();
linkedMap.put("/add","authc");
linkedMap.put("/","anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(linkedMap);
shiroFilterFactoryBean.setLoginUrl("/login");

便可实现登录的拦截 

3.2用户认证 

首先需要在controller层接收用户传递的账号与密码

@RequestMapping("/login")
    public String login(String username, String password, Model model)
    {
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登录信息
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);
        try {
            subject.login(usernamePasswordToken);
            return "index";
        } catch (UnknownAccountException e) {
            model.addAttribute("msg","用户名错误");
            e.printStackTrace();
            return "login";
        }catch (IncorrectCredentialsException e)
        {
            model.addAttribute("msg","密码错误");
            return "login";
        }

Token可以说是一个 令牌,可以全局使用,将username与password放于令牌中,在后面的操作中可在myrealm中的认证方法中通过他直接获取username和password。

myrealm编写认证方法

@Override
    //认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            User user = userService.getUserByUsername(token.getUsername());
            // 我这块就写了一个异常
            if (user == null) {
                    throw new UnknownAccountException();
                }
            // 实际上有好些异常可以往外抛
            // IncorrectCredentialsException 凭证错误 可以理解为密码错误
            // DisabledAccountException 账号被禁用
            // LockedAccountException 账号被锁定
            // ExcessiveAttemptsException 登录失败次数超过限制
            // ... 还有好些 他们都是 AuthenticationException的子类

            // 这里返回一个认证信息
            return new SimpleAuthenticationInfo(user.getUsername(), user.getPwd(), getName());
    }

 根据username查出数据库中对应的数据,封装于user中,值得注意的是,这个方法是直接把密码的判断封装起来,我们是看不到判断的过程的,我们只需返回AuthenticationInfo的实现类,根据代码填入相应的参数。至此认证便完成了

 3.3用户权限

首先我们可以在shrioconfig通过map设置哪些页面需要权限控制

Map linkedMap = new LinkedHashMap<String,Object>();
linkedMap.put("/add","authc");
linkedMap.put("/update","authc");
linkedMap.put("/add","roles[vip1]");
linkedMap.put("/update","roles[vip1]");
linkedMap.put("/","anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(linkedMap);
shiroFilterFactoryBean.setLoginUrl("/tologin");

已这个为例子,至于为什么权限要这么些(roles[vip1]),这是官方的文档中ini文件中的写法,这里提醒一下。

其次我们便可以在自定义的realm中的权限方法中编写想要的逻辑

@Override
    // 这块是权限鉴定 就是登录成功后把权限查出来,授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 首先要把用户查出来
        User user = userService.getUserByUsername(principalCollection.toString());
        // 然后把他的角色和权限查出来 扔进
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(user.getRole());
        return info;
    }

至此简单的权限认证便实现完了,主要还是要知道,subject,scurityManager、realm这三个核心对象,subject往往被使用在realm中进行获取对象。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值