Springboot+shiro+mybatis+druid+thymeleaf

146 阅读1分钟

导入依赖

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.29</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring-boot-web-starter -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-web-starter</artifactId>
    <version>1.9.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.1.0</version>
</dependency>

配置application.yaml

mybatis:
  # 指定 mapper.xml 的位置
  mapper-locations: classpath:mapper/*.xml
  #扫描实体类的位置,在此处指明扫描实体类的包,在 mapper.xml 中就可以不写实体类的全路径名
  type-aliases-package: com.hao.pojo
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/admin

配置shiro

@Configuration
public class ShiroConfig {

    // Subject
    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); //设置安全管理器

        //添加过滤器
        /**
         * anon:无需认证就可以访问
         * authc: 必须认证才能访问
         * user: 必须拥有记住我才能访问
         * perms: 拥有对某个资源权限才能访问
         * role: 拥有某个角色权限才能访问
         * */
        Map map = new LinkedMap();
        map.put("/add","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setLoginUrl("/out"); //如果被拦截了就会跳到login页面


        return shiroFilterFactoryBean;
    }


    // SecurityManger
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("Realm") UserRealm userRealm){
        DefaultWebSecurityManager SecurityManger = new DefaultWebSecurityManager();
        SecurityManger.setRealm(userRealm); //关联Realm
        return SecurityManger;
    }

    //Realm
    @Bean(name="Realm")
    public UserRealm userRealm(){
        return new UserRealm();
    }
    
    //整合shiro和thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

}

这里需要一个Realm,所以要创建

//自定义Realm
@Configuration
public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserMapper userMapper;

    @Override //授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override //认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            //账号验证
        User user = userMapper.selectbyname(token.getUsername());
        if (user==null){
            return null;
        }
        return new SimpleAuthenticationInfo("",user.getPassword(),"");
    }
}

上面写了登入就跳到登入controller那,这里给个简便的写法,到时候根据自己需求改

@PostMapping("/login")
public String login(User user, Model model){
    //获取当前用户
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
    try {
        subject.login(token);
        return "index";
    } catch (UnknownAccountException e) {
        model.addAttribute("msg","用户名错误");
        return "login";
    } catch (IncorrectCredentialsException e){
        model.addAttribute("msg","密码错误");
        return "login";
    }

}