Java 杂谈iOS技术交流收藏程序员

SpringBoot:集成Shiro之INI认证篇

2018-09-06  本文已影响41人  神经骚栋

前言


上一篇SpringBoot:集成Shiro之简述篇中,我们简述了Shiro的基本概念以及Shiro的内部流程方式.下面我先简述一下本篇博客的基本内容以及使用场景.

本篇博客主要是讲 在SpringBoot 2.0 中集成Shiro,使用INI文件的形式完成登录认证(只认证非授权),使用场景只应对较少的用户的系统,而且账号密码为固定.

集成环境 : Mac   |   JDK 1.8   |   SpringBoot 2.0

❗️❗️❗️ INI文件优缺点必看,因为这是你架构程序的第一步!

INI文件优势 : 简单易懂 , 集成方便.
INI文件缺点 : 采用硬编码方式把认证授权信息写在INI文件中,可维护性差.

搭建Shiro基本环境


首先,我们先使用IDEA创建一个SpringBoot 2.0的web工程(关于JDK,这里我就不多说了).具体过程如下所示.

        <!-- shiro用户权限管理 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId>
            <version>1.4.0</version>
        </dependency>

配置INI文件认证部分


当工程所有都配置完成之后,我们运行Shiro项目,发现并不能运行成功,报错信息如下所示.

***************************
APPLICATION FAILED TO START
***************************

Description:

No bean of type 'org.apache.shiro.realm.Realm' found.

Action:

Please create bean of type 'Realm' or add a shiro.ini in the root classpath (src/main/resources/shiro.ini) or in the META-INF folder (src/main/resources/META-INF/shiro.ini).

这是因为我们没有配置INI文件,所以我们根据提示在resources或者src/main/resources/META-INF文件夹下创建一个名为shiro.ini的文件.并且添加我们的用户验证信息.如下图所示.

然后,我们把下面的用户信息写入shiro.ini文件中.其中用户root密码为123456,用户admin的密码为admin.

[users]
root=123456
admin=admin

认证逻辑代码


下面的一张图是上一篇博客中讲述的,上一个模块的INI文件就是对应图中的Realm.现在我们所需要做的工作内容就是组装Subject主体,以及配置Secruity Manager.

为了保证代码的逻辑性,我们把验证逻辑抽到一个类中.然后我们开始根据INI文件创建SecurityManager并且绑定到SecurityUtils中,整体代码如下所示.

        //初始化SecurityManager对象
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

        //通过SecurityManager工厂对象,获取SecurityManager实例对象.
        SecurityManager securityManager =  factory.getInstance();

        // 把 securityManager 实例 绑定到 SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);

紧接着,我们开始获取我们Subject主体,以及配置我们的用户信息token令牌,如下所示.

        //组建Subject主体.
        Subject subject = SecurityUtils.getSubject();

        //创建 token 令牌
        UsernamePasswordToken token = new UsernamePasswordToken(userName,passWord);

接下来我们就需要进行token令牌认证了,这里我需要说明一下,用户登录不成功有两种情况,一为用户不存在,二为用户密码不正确.所以我们要crash出对应的错误,然后通过不同的错误类型,进行数据的返回.这里我就统一用一种错误表示了.不做细分处理了.具体代码如下所示.

        //用户登录操作.
        try{
            subject.login(token);
            resultMap.put("code","200");
            resultMap.put("msg","用户登录成功");
        }catch (AuthenticationException e){
            //登录失败原因 1 用户不存在 2 用户密码不正确
            e.printStackTrace();
            resultMap.put("code","-1");
            resultMap.put("msg","用户登录失败");
        }

上面就完成了 构建Secruity Manager对象组建Subject主体通过Realm完成认证过程 三个步骤.接下来我们需要封装一下,所以MyShiro整体代码如下所示.

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;


@Component
public class MyShiro {


    public Map<String,Object> userLoginAction (String userName,String passWord){

        Map<String,Object> resultMap = new HashMap<>();

        //初始化SecurityManager对象
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

        //通过SecurityManager工厂对象,获取SecurityManager实例对象.
        SecurityManager securityManager =  factory.getInstance();

        // 把 securityManager 实例 绑定到 SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);

        //组建Subject主体.
        Subject subject = SecurityUtils.getSubject();

        //创建 token 令牌
        UsernamePasswordToken token = new UsernamePasswordToken(userName,passWord);

        //用户登录操作.
        try{
            subject.login(token);
            resultMap.put("code","200");
            resultMap.put("msg","用户登录成功");
        }catch (AuthenticationException e){
            //登录失败原因 1 用户不存在 2 用户密码不正确
            resultMap.put("code","-1");
            resultMap.put("msg","用户登录失败");
        }
        return resultMap;

    }
}

添加 @Component 的原因是为了方便在下一模块使用自动化创建.

用户登录接口


上面我们已经完成了认证流程的封装,然后接下来,我们写一个简单的用户登录接口,验证我们的shiro是否能够正常的使用.

首先创建一个用户登录接口控制器UserLoginController,导入MyShiro.并且创建一个用户登录接口方法.代码过于简单,这里就不过叙述了 ,整体代码如下所示.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class UserLoginController {

    @Autowired
    MyShiro myShiro;

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public Map<String,Object> userLoginAction (@RequestParam(value = "userName") String userName,
                                               @RequestParam(value = "password") String password){

        Map<String,Object> resultMap = myShiro.userLoginAction(userName,password);

        return resultMap;

    }
    
}

接下来我们就运行我们的项目,然后查看我们用户是否能够登录成功.


用户登录成功 用户登录失败

结语


到这里,SpringBoot2.0集成Shiro之INI认证篇就完结了,使用INI文件做用户认证操作还是很简单的.下一篇,我们将看一下,如何使用INI文件进行授权操作,欢迎继续关注,如果有任何问题,欢迎一切和骚栋探讨~感谢大家.

上一篇 下一篇

猜你喜欢

热点阅读