系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 数据库 > Mysql > 详细页面

Shiro+SpringBoot认证

时间:2020-08-13来源:www.pcxitongcheng.com作者:电脑系统城

一、引入依赖

    shiro-all包含shiro所有的包、shiro-core是核心包、shiro-web是与web整合、shiro-spring是与spring整合、shiro-ehcache是与EHCache整合、shiro-quartz是与任务调度quartz整合等等。这里我们只需要引入shiro-spring即可。

 

1 <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
2 <dependency>
3      <groupId>org.apache.shiro</groupId>
4      <artifactId>shiro-spring</artifactId>
5      <version>1.5.3</version>
6 </dependency>

 二、Controller层

复制代码
@RestController
@RequestMapping("/account")
public class AccountController {

/**
 * 登录
 * @param username
 * @param password
 * @return
 */
  @PostMapping(path = "/login")
    public ResultMsg login(
            @RequestParam(value = "aaccount")String username,
            @RequestParam(value = "apassword")String pwd,
            @RequestParam("check") Integer check ) {
        ResultMsg resultMsg = new ResultMsg();
        //        获取当前用户
        Subject subject = SecurityUtils.getSubject();
        /**
         * 判断当前用户是否已经认证过
         */
//        System.out.println("是否记住我==="+subject.isRemembered());
        if (!subject.isAuthenticated()) {
    //            封装用户的登录数据
            UsernamePasswordToken token = new UsernamePasswordToken(username,pwd);
            Boolean rememberMe = check == 1 ? true:false;
            System.out.println(rememberMe);
            token.setRememberMe(rememberMe); //记住我
            try {
                subject.login(token); //登录认证
                resultMsg.setState(200);
                resultMsg.setMsg("登录成功");
                return resultMsg;
            } catch (UnknownAccountException u) {
                System.err.println("用户不存在");
                resultMsg.setState(412);
                resultMsg.setMsg("用户不存在");
                return resultMsg;
            } catch (IncorrectCredentialsException i) {
                System.err.println("密码错误");
                resultMsg.setState(412);
                resultMsg.setMsg("密码错误");
                return resultMsg;
            } catch (LockedAccountException l) {
                System.err.println("账户锁定");
                resultMsg.setState(412);
                resultMsg.setMsg("账户锁定");
                return resultMsg;
            }
        } else {
            resultMsg.setState(403);
            resultMsg.setMsg("此账户已在其他地方登录,是否强制下线?");
            return resultMsg;
        }
    }
  
  /**
     * 退出登录
     * @param num
     * @return
     */
    @GetMapping(path = "/loginout")
    public ResultMsg loginOut(Integer num) {
        ResultMsg resultMsg = new ResultMsg();
//        获取当前用户
        Subject subject = SecurityUtils.getSubject();
        subject.logout();//退出当前登录
        resultMsg.setState(200);
        if (num == 1) {
            resultMsg.setMsg("已下线!");
        } else {
            resultMsg.setMsg("当前用户已退出!");
        }
        return resultMsg;

    }
  
  /**
   * 未认证返回登录页面
   * @return
   */
  @GetMapping(path = "/login")
  public ModelAndView login() {
      ModelAndView mv = new ModelAndView("/user/login");
      return mv;
  }


}
复制代码

Shiro核心配置

Shiro配置类

ShiroConfig.java

主要创建三大Bean对象

  • ShiroFilterFactoryBean(拦截一切请求)3
  • DefaultSecurityManager(安全管理器)2
  • 自定义Realm 继承 AuthorizingRealm(主要用于认证和授权)1

建议创建顺序逆行

复制代码
package com.hk.aefz.shiro.config;

@Configuration
public class ShiroConfig {

    //    ShiroFliterFactoryBean 3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(
            @Qualifier("securityManager") DefaultWebSecurityManager securityManager
    ) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
//        设置安全管理器
        factoryBean.setSecurityManager(securityManager);
//        添加Shiro内置过滤器
    /*
            anon:无需认证就可以访问
            authc:必须认证才可以访问
            user:必须拥有记住我功能才可以访问
            perms:拥有对某个资源的权限才能访问
            role:拥有某个角色权限才可以访问
         */

        Map<String, String> filterMap = new LinkedHashMap<>();
//        匿名访问
        filterMap.put("/navigation/index","anon");
        filterMap.put("/navigation/blogdetails","anon");
        filterMap.put("/navigation/login","anon");
        filterMap.put("/navigation/register","anon");
//        需要角色
        filterMap.put("/navigation/personblog","authc,roles[blogger]");
        filterMap.put("/navigation/admin-blog","authc,roles[blogger]");
        filterMap.put("/navigation/**","user");
        factoryBean.setFilterChainDefinitionMap(filterMap);
//        拦截后返回登录页面
        factoryBean.setLoginUrl("/navigation/login");return factoryBean;
    }

    //  DefaultWebSecurityManager 2 安全管理器
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(
            @Qualifier("userRealm") UserRealm userRealm,
    ) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        关联UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //    创建UserRealm类 需要自定义 1
    @Bean
    public UserRealm  userRealm() {
        UserRealm userRealm = new UserRealm();
   
        return userRealm;
    }
    }
}
复制代码

自定义Relam类

继承AuthorizingRealm类

复制代码
/**
 * 自定义UserRealm
 */
public class UserRealm extends AuthorizingRealm {

//    注入AccountController
    @Autowired
    private AccountController accountController;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private AccountService accountService;

//    授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.err.println("执行了授权.........");return null;
    }

//    认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.err.println("执行了认证...........");
//        获取当前登录账户
        UsernamePasswordToken accountToken = (UsernamePasswordToken) token;
        String username = accountToken.getUsername(); // 获取当前账号
//        连接数据库进行登录验证
        Account account = accountController.selectByName(username);
        System.out.println(account);
        if (account == null) {
            return null; //抛出 UnknownAccountException 异常
        }
//         密码认证 shiro做 存在泄密
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(account, account.getApassword(), account.getAaccount());return info;
    }

}
复制代码

测试

使用PostMan进行登录测试

 

分享到:

相关信息

  • MySQL的核心查询语句详解

    一、单表查询 1、排序 2、聚合函数 3、分组 4、limit 二、SQL约束 1、主键约束 2、非空约束 3、唯一约束 4、外键约束 5、默认值 三、多表查询 1、内连接 1)隐式内连接: 2)显式内连接: 2、外连接 1)左外连接 2)右外连接 四...

    2023-10-30

  • Mysql中如何删除表重复数据

    Mysql删除表重复数据 表里存在唯一主键 没有主键时删除重复数据 Mysql删除表中重复数据并保留一条 准备一张表 用的是mysql8 大家自行更改 创建表并添加四条相同的数据...

    2023-10-30

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载