Loading

用户认证

继上一篇登录拦截登录拦截

导入依赖

     <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.10</version>
    </dependency>
    <!--log4j-->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <!--druid-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.21</version>
    </dependency>
    <!--数据库-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--Mybatis官方提供的适配Spring Boot 的,而不是SpringBoot的-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.0</version>
    </dependency>
    <!--导入shiro的spring的整合包-->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.4.1</version>
    </dependency>
    <!--thymeleaf模板-->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring5</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-java8time</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

编写一个application.yml配置文件


spring:
  datasource:
    username: root
    password: 123456
    # 假如市区报错了,就增加一个时区的配置就ok了  serverTimezone=UTC
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 5 # 初始化大小
    minIdle: 5     # 最小连接数
    maxActive: 20  # 最大连接数
    maxWait: 60000 # 取连接等待超时的时间
    timeBetweenEvictionRunsMillis: 60000  # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    minEvictableIdleTimeMillis: 300000    # 配置一个连接在池中最小生存的时间,单位是毫秒
    validationQuery: SELECT 1 FROM DUAL   # 验证连接有效与否的SQL,不同的数据配置不同
    testWhileIdle: true

    # 这里建议配置为TRUE,防止取到的连接不可用
    testOnBorrow: false
    testOnReturn: false

    poolPreparedStatements: true

    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

在application.propertiea写mybatis配置

      mybatis.type-aliases-package=com.rzk.pojo
      mybatis.mapper-locations=classpath:mapper/*.xml

pojo包下的user

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
    private String perms;
}

mapper接口

  User queryUserByName(String name);

resources下mapper包下mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--configguration核心配置文件-->
<mapper namespace="com.rzk.mapper.UserMapper">
    
    <select id="queryUserByName" parameterType="String" resultType="User">
        select * from user where name=#{name}
    </select>
</mapper>

service

    @Autowired
    public UserMapper userMapper;

    @Override
    public User queryUserByName(String name) {
        return userMapper.queryUserByName(name);
    }

测试

login.html

<p th:text="${msg}" style="color: crimson"></p>
<form th:action="@{/login}">
    <p>用户:<input type="text" name="username"></p>
    <p>密码:<input type="text" name="password"></p>
    <p><input type="submit"></p>
</form>

编写MyController

这一段是根据官方给的例子看


        // 判断当前的用户是否被认证
        if (!currentUser.isAuthenticated()) {
            //Token  : 令牌
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);//设置记住我
            try {
                currentUser.login(token);//执行登录操作
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
            }
        }

controller代码


    @RequestMapping("/login")
    public String login(String username,String password,Model model){
        //获取当前的用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户登录数据
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        try{
            subject.login(token);//执行登录方法,如果都没有异常就显示说明ok
            return "index";
        }catch (UnknownAccountException e){//用户名不存在
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch(IncorrectCredentialsException ice) {//密码不存在
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }

认证

用户登录会走 自定义的UserRealm的doGetAuthenticationInfo请求

在认证方法里面获取用户名密码

  //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了=>认证doGetAuthenticationInfo");

        UsernamePasswordToken userToken = (UsernamePasswordToken) token;

        //用户名  密码
        User user = userService.queryUserByName(userToken.getUsername());

        if (user==null){//沒有查到此人
            return null;//会抛出异常  UnknownAccount
        }

        Subject sub = SecurityUtils.getSubject();
        Session session = sub.getSession();
        session.setAttribute("loginUser",user);

        //密码认证shiro做
        //把第一个参数的user传到 授权的subject里面,subject就能拿到用户对象
        return new SimpleAuthenticationInfo(user,user.getPwd(),"");
    }

测试

以 李四 123456 账号登录

密码错误进行登录

密码正确进行登录

posted @ 2020-05-30 02:18  Rzk  阅读(219)  评论(0)    收藏  举报