美文网首页
shiro springboot 认证

shiro springboot 认证

作者: 杨健kimyeung | 来源:发表于2020-08-25 13:17 被阅读0次
    1. 导入相关依赖

    2. 配置shiro

      2.1 配置类
      2.2 登录页配置
      2.3 shiro默认过滤器

    3. 自定义Reaml类

    4. 用户登录
      3.1 页面设计
      3.2 登录处理
      3.3 密码匹配原理

    1、导入依赖

    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring-boot-web-starter</artifactId>
      <version>1.5.2</version>
    </dependency>
    

    2、配置shiro

    starter已经做了很多自动配置工作,具体可以参考ShiroAutoConfiguration.java、ShiroBeanAutoConfiguration.java和ShiroWebAutoConfiguration.java这几个文件

    @Configuration
    public class ShiroConfig {
        /**
         * 1. 注册自定义Realm
         */
        @Bean
        public UserRealm realm() {
            return new UserRealm();
        }
        /**
         * 2. 配置url过滤器
         * 统一做鉴权,即判断哪些请求路径需要用户登录,哪些请求路径不需要用户登录。
         * 只做鉴权,不做权限控制,因为权限用注解来实现。
         *
         * @return
         */
        @Bean
        public ShiroFilterChainDefinition shiroFilterChainDefinition() {
            DefaultShiroFilterChainDefinition shiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
            //不需要认证就能访问
            shiroFilterChainDefinition.addPathDefinition("/test/**", "anon");
            shiroFilterChainDefinition.addPathDefinition("/login", "anon");
            shiroFilterChainDefinition.addPathDefinition("/register", "anon");
            shiroFilterChainDefinition.addPathDefinition("/druid/**", "anon");
            //需要认证才能访问的
            shiroFilterChainDefinition.addPathDefinition("/admin/**", "authc");
            shiroFilterChainDefinition.addPathDefinition("/user/**", "authc");
            shiroFilterChainDefinition.addPathDefinition("/api/**", "authc");
            shiroFilterChainDefinition.addPathDefinition("/**", "authc");
            return shiroFilterChainDefinition;
        }
      
        /**
         * 3 配置security并设置Realm,避免required a bean named 'authorizer' that could not be found.的报错
         * @param realm
         * @return
         */
        @Bean
        public DefaultWebSecurityManager securityManager(UserRealm realm) {
            DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
            defaultWebSecurityManager.setRealm(realm);
            return defaultWebSecurityManager;
        }
    

    3、自定义Realm

    public class UserRealm extends AuthorizingRealm {
        @Resource
        UserService userService;
            
        /**
         * 认证
         * @param authenticationToken
         * @return
         * @throws AuthenticationException
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
           //第一步:从token中取出用户名,这个用户名是用户在页面输入的信息,传递给token
            String username = (String) authenticationToken.getPrincipal();
           // 第二步通过用户名从数据库中查询出用户信息
            User user = userService.findUserByName(username);
           //  第三步 判断
            if (user == null) {
                throw new UnknownAccountException("账号不存在");
            }
            if (user.getStatus() == 0) {
                throw new LockedAccountException("账号被锁定!请与管理员联系");
            }
                    // 第四步 实例化 SimpleAuthenticationInfo
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    user, user.getPassword(), getName()
            );
            return authenticationInfo;
        }
        /**
         * 授权
         * @param principalCollection
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            return null;
        }
    }
    

    SimpleAuthenticationInfo 参数说明

    参数 说明 备注
    principal 从数据库中查询的user对象,也可以user对象的用户名。传入的一般都是user对象。 必要
    hashedCredentials 传的是从数据库中获取的password,然后再与token中的password进行对比,匹配上了就通过,匹配不上就报异常。 必要
    credentialsSalt 加密盐–用于加密密码对比,为了防止两用户的初始密码是一样的, 非必要
    realmName 从authenticationToken中获取的用户名 必要

    3、登录

    在控制层的登录方法中,

    创建一个usernamePasswordToken令牌,交由Shiro并调用login()方法进行登录,

    如果不抛出任何异常表明登录成功,

    如果抛出异常,根据异常种类返回提示出错信息

    @RestController
    public class LoginController {
        @PostMapping("login")
        public String login(String username, String password) {
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
            try {
                SecurityUtils.getSubject().login(usernamePasswordToken);
            } catch (IncorrectCredentialsException e) {
                throw new CustomShiroException("账号或密码错误");
            } catch (ExcessiveAttemptsException e) {
                throw new CustomShiroException("操作过于频繁,请稍后在试!");
            }
            return "success";
        }
    }
    

    相关文章

      网友评论

          本文标题:shiro springboot 认证

          本文链接:https://www.haomeiwen.com/subject/odzajktx.html