3

Shiro框架简介

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

Apache Shiro 体系结构
image.png
1、Authentication 认证 ---- 用户登录
2、Authorization 授权 --- 用户具有哪些权限
3、Cryptography 安全数据加密
4、Session Management 会话管理
5、Web Integration web系统集成
6、Interations 集成其它应用,spring、缓存框架

进入主题

1、导入对应的依赖
如果需要连接数据库的话,别忘记导入相应的坐标。

image.png

image.png
这里先看一眼对应的目录结构
image.png
2、编写controller类
在controller类里面我们可以测试thymeleaf

@RequestMapping("/testThymeleaf")
    public String testThymeleaf(Model model){
        //把数据存入model
        model.addAttribute("name", "黑马程序员");
        //返回test.html
        return "test";
    }

对应的主题部分:

/**
     * 登录逻辑处理
     */
    @RequestMapping("/login")
    public String login(String name,String password,Model model){
        System.out.println("name="+name);
        /**
         * 使用Shiro编写认证操作
         */
        //1.获取Subject
        Subject subject = SecurityUtils.getSubject();
        
        //2.封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(name,password);
        
        //3.执行登录方法
        try {
            subject.login(token);
            
            //登录成功
            //跳转到test.html
            return "redirect:/testThymeleaf";
        } catch (UnknownAccountException e) {
            //e.printStackTrace();
            //登录失败:用户名不存在
            model.addAttribute("msg", "用户名不存在");
            return "login";
        }catch (IncorrectCredentialsException e) {
            //e.printStackTrace();
            //登录失败:密码错误
            model.addAttribute("msg", "密码错误");
            return "login";
        }
    }

3、Spring Boot与Shiro整合实现用户认证
3.1分析Shiro的核心API
Subject: 用户主体(把操作交给SecurityManager)
SecurityManager:安全管理器(关联Realm)
Realm:Shiro连接数据的桥梁
3.2自定义Realm类

public class UserRealm extends AuthorizingRealm{

    /**
     * 执行授权逻辑
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
        System.out.println("执行授权逻辑");
        
        //给资源进行授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        
        //添加资源的授权字符串
        //info.addStringPermission("user:add");
        
        //到数据库查询当前登录用户的授权字符串
        //获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();
        User dbUser = userSerivce.findById(user.getId());
        
        info.addStringPermission(dbUser.getPerms());
        
        return info;
    }
    
    @Autowired
    private UserService userSerivce;

    /**
     * 执行认证逻辑
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
        System.out.println("执行认证逻辑");
        
        //编写shiro判断逻辑,判断用户名和密码
        //1.判断用户名
        UsernamePasswordToken token = (UsernamePasswordToken)arg0;
        
        User user = userSerivce.findByName(token.getUsername());
        
        if(user==null){
            //用户名不存在
            return null;//shiro底层会抛出UnKnowAccountException
        }
        
        //2.判断密码
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

3.3编写Shiro配置类(*)

@Configuration
public class ShiroConfig {

    /**
     * 创建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        
        //添加Shiro内置过滤器
        /**
         * Shiro内置过滤器,可以实现权限相关的拦截器
         *    常用的过滤器:
         *       anon: 无需认证(登录)可以访问
         *       authc: 必须认证才可以访问
         *       user: 如果使用rememberMe的功能可以直接访问
         *       perms: 该资源必须得到资源权限才可以访问
         *       role: 该资源必须得到角色权限才可以访问
         */
        Map<String,String> filterMap = new LinkedHashMap<String,String>();
        /*filterMap.put("/add", "authc");
        filterMap.put("/update", "authc");*/
        
        filterMap.put("/testThymeleaf", "anon");
        //放行login.html页面
        filterMap.put("/login", "anon");
        
        //授权过滤器
        //注意:当前授权拦截后,shiro会自动跳转到未授权页面
        filterMap.put("/add", "perms[user:add]");
        filterMap.put("/update", "perms[user:update]");
        
        filterMap.put("/*", "authc");
        
        //修改调整的登录页面
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        //设置未授权提示页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        
        
        return shiroFilterFactoryBean;
    }
    
    /**
     * 创建DefaultWebSecurityManager
     */
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    
    /**
     * 创建Realm
     */
    @Bean(name="userRealm")
    public UserRealm getRealm(){
        return new UserRealm();
    }
    
    /**
     * 配置ShiroDialect,用于thymeleaf和shiro标签配合使用
     */
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

3.4使用Shiro内置过滤器实现页面拦截
代码见上块。。。
3.5实现用户认证(登录)操作

<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h3>登录</h3>
<h3 th:text="${msg}" style="color: red"></h3>

<form method="post" action="login">
    用户名:<input type="text" name="name"/><br/>
    密码:<input type="password" name="password"/><br/>
    <input type="submit" value="登录"/>
</form>
</body>
</html>

至于service层和mapper层,这里不在赘述!
需要源码的可以在我的csdn里面进行留言!!!


Nice
48 声望13 粉丝

在校大二学生一枚,主要专注于 JAVA 后端技术栈,以后会经常发布以下自己学的知识和笔记 ,坚持学习和写作,加油,奥力给!!