博客
关于我
springboot整合shiro
阅读量:367 次
发布时间:2019-03-04

本文共 10517 字,大约阅读时间需要 35 分钟。

springboot整合shiro

使用
springboot整合shiro其实和使用
SSM整合shiro很相似,只不过使用springboot整合shiro中间简化了很多文件配置,但是主体内容基本一致

1.springboot整合shiro

1.1项目结构图

在这里插入图片描述

1.2访问流程

在这里插入图片描述

1.3项目内容

1.3.1配置类及pom文件

  • 项目启动类
@SpringBootApplication@MapperScan("com.fyx.dao")//包扫描public class Day0408SpringbootApplication {       public static void main(String[] args) {           SpringApplication.run(Day0408SpringbootApplication.class, args);    }}
  • ①首先创建springboot项目,在pom.xml文件中导入相关依赖。
org.springframework.boot
spring-boot-starter-web
com.baomidou
mybatis-plus-boot-starter
3.4.2
com.alibaba
druid-spring-boot-starter
1.1.14
org.apache.shiro
shiro-spring-boot-starter
1.4.1
org.springframework.boot
spring-boot-starter-thymeleaf
com.github.theborakompanioni
thymeleaf-extras-shiro
2.0.0
com.alibaba
fastjson
1.2.62
mysql
mysql-connector-java
5.1.47
org.springframework.boot
spring-boot-configuration-processor
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
  • ②application.properties
# 配置数据源spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driverspring.datasource.druid.url=jdbc:mysql:///shirospring.datasource.druid.username=rootspring.datasource.druid.password=123@qwe
  • shiro的配置文件

在ssm项目中,shiro的组件创建在spring配置文件中,在springboot项目中,需要自己创建一个配置类

ShiroConfig类

@Configuration//等价于spring的配置文件public class ShiroConfig {       //    配置安全管理器    @Bean("securityManager")    public DefaultWebSecurityManager securityManager(Realm myRealm){           DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();        securityManager.setRealm(myRealm);        return securityManager;    }    //  创建MyRealm对象    @Bean(value = "myRealm")//依赖注入    public Realm getRealm(CredentialsMatcher credentialsMatcher){           MyRealm myRealm = new MyRealm();        myRealm.setCredentialsMatcher(credentialsMatcher);        return myRealm;    }    @Bean(value = "credentialsMatcher")//密码配置器    public CredentialsMatcher getCredentialsMatcher(){           HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();        credentialsMatcher.setHashIterations(1024);//散列次数        credentialsMatcher.setHashAlgorithmName("MD5");//使用MD5加密        return credentialsMatcher;    }    //    配置过滤规则    @Bean("shiroFilter")//shiro过滤    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){           ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();        shiroFilterFactoryBean.setSecurityManager(securityManager);        shiroFilterFactoryBean.setLoginUrl("/tologin");//路径        shiroFilterFactoryBean.setSuccessUrl("/success.html");//访问成功后调转的路径        HashMap
map = new HashMap<>(); map.put("/index.html","anon");// map.put("/static/**","anon"); map.put("/login","anon"); map.put("/**","authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; } // 配置过滤器 相当于ssm项目中web.xml的给shiro配置过滤器 @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(); filterRegistrationBean.setName("shiroFilter"); filterRegistrationBean.setFilter(new DelegatingFilterProxy()); filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } //使shiro标签库可以在thymeleaf中使用 @Bean public ShiroDialect shiroDialect() { return new ShiroDialect(); }}

1.3.2html文件

springboot项目不支持jsp,只能使用html,要使用thymeleaf模板,需要导入依赖

org.springframework.boot
spring-boot-starter-thymeleaf
  • login.html
    
Title
账号:
密码:
  • success.html
    在这个页面中需要使用shiro的标签,要在页面中引入shiro的标签,也要在pom.xml中引入依赖
com.github.theborakompanioni
thymeleaf-extras-shiro
2.0.0
    
成功页面成功

欢迎来到xxx班 尽情欢呼!

查询所有用户
修改用户
删除用户
添加用户
导出用户
  • un.html
    
Title无权访问

1.3.3后端类文件

  • dao层
    ①UserDao
public interface UserDao extends BaseMapper
{ /** * 根据用户id查询该用户具有的权限 * @param userid * @return */ List
findPermissionByUserid(Integer userid);}

②PermissionDao

public interface PermissionDao {       /**     * 根据userid查询用户权限     */    List
findAllPermissionByUserId(Integer userid);}
  • entity层
    User
@Data@AllArgsConstructor@NoArgsConstructorpublic class User {       private Integer userid;    private String username;    private String userpwd;    private String  sex;    private String  address;    private String  salt;//盐}
  • service层
    ①UserService
public interface UserService {       User selectByUsername(String username);}

②UserServiceImpl

@Servicepublic class UserServiceImpl implements UserService {       @Resource    private UserDao userDao;    @Override    public User selectByUsername(String username) {           //条件构造器        QueryWrapper
wrapper = new QueryWrapper<>(); wrapper.eq("username",username);//相当于username=#{username} User user = userDao.selectOne(wrapper); return user; }}
  • user的映射文件
  • Controller层
    ①PageController
@Controllerpublic class PageController {       @GetMapping("tologin")    public String tologin(){           return "login";    }}

②LoginController

@Controllerpublic class LoginController {       @PostMapping("login")    public String login(String username,String userpwd){           Subject subject = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(username,userpwd);        try{               subject.login(token);//开始认证            return "success";        }catch (Exception e){               return "redirect:/tologin";        }    }}

③UserController

@RestController@RequestMapping("user")public class UserController {       @GetMapping("query")    @RequiresPermissions("user:query")//当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。    public String query(){           return "user:query";    }    @GetMapping("delete")    @RequiresPermissions("user:delete")    public String delete(){           return "user:delete";    }    @GetMapping("update")    @RequiresPermissions("user:update")    public String update(){           return "user:update";    }    @GetMapping("insert")    @RequiresPermissions("user:insert")    public String insert(){           return "user:insert";    }    @GetMapping("export")    @RequiresPermissions("user:export") //@Transcational    public String export(){           return "user:export";    }}
  • handler层

ExceptionController : 处理异常

@ControllerAdvicepublic class ExceptionController {       @ExceptionHandler(value = AuthorizationException.class)    public String handler(){           return "un";    }}
  • realm层

MyRealm类

public class MyRealm extends AuthorizingRealm {       @Resource    private UserService userService;    @Resource    private PermissionService permissionService;    //授权    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {           //查询用户权限信息        User user = (User)principalCollection.getPrimaryPrincipal();        //通过userid查询对应用户所具有的权限        List
userId = permissionService.findAllPermissionByUserId(user.getUserid()); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //判断查询的权限集合是否有值 if (userId.size()>0){ //将权限添加到授权对象中 info.addStringPermissions(userId); } return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //获取前台传的用户名 String username = authenticationToken.getPrincipal().toString(); User user = userService.selectByUsername(username); if (user!=null){ ByteSource bytes = ByteSource.Util.bytes(user.getSalt()); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getUserpwd(),bytes,this.getName()); return info; } return null; }}
  • 测试
    在这里插入图片描述
    在这里插入图片描述

2.springboot整合shiro完全分离

前后端完成分离,后端返回给访问者的是json数据

该项目中有三个地方需要改造返回json数据:

1、认证成功或认证失败时
2、出现异常时,例如权限不足时
3、未登录访问时

  • ①创建返回的json数据格式的Result类
@Data@NoArgsConstructor@AllArgsConstructorpublic class Result {       private Integer code;    private String msg;    private Object data;}
  • ②改造Controller

将Controller层的@Controller都改成@RestController,将@ControllerAdvice改成@RestControllerAdvice

LoginController

@PostMapping("login")    public Result login(String username, String userpwd){           Subject subject = SecurityUtils.getSubject();        UsernamePasswordToken token=new UsernamePasswordToken(username,userpwd);        try {               subject.login(token);//realm的认证功能//getPrincipl()可以得到SimpleAuthenticationInfo中的数据            Object user = subject.getPrincipal();            return new Result(2000,"登陆成功",user);        }catch (Exception e){               return new Result(5000,"登陆失败",null);        }    }
  • ②改PageController

PageController

@RestControllerpublic class PageController {       @GetMapping("/tologin")    public Result loginPage(){           return new Result(5002,"请先登录",null);    }}
  • ExceptionController 异常处理类
@RestControllerAdvicepublic class MyHandlerException {       @ExceptionHandler(value = UnauthorizedException.class)    public ResultunauthorizedException(){           return new Result(5001,"权限不足",null);    }}
  • 测试
    在这里插入图片描述
    在这里插入图片描述

转载地址:http://tfzg.baihongyu.com/

你可能感兴趣的文章
Mysql INNODB引擎行锁的3种算法 Record Lock Next-Key Lock Grap Lock
查看>>
mysql InnoDB数据存储引擎 的B+树索引原理
查看>>
mysql innodb通过使用mvcc来实现可重复读
查看>>
mysql insert update 同时执行_MySQL进阶三板斧(三)看清“触发器 (Trigger)”的真实面目...
查看>>
mysql interval显示条件值_MySQL INTERVAL关键字可以使用哪些不同的单位值?
查看>>
Mysql join原理
查看>>
MySQL Join算法与调优白皮书(二)
查看>>
Mysql order by与limit混用陷阱
查看>>
Mysql order by与limit混用陷阱
查看>>
mysql order by多个字段排序
查看>>
MySQL Order By实现原理分析和Filesort优化
查看>>
mysql problems
查看>>
mysql replace first,MySQL中处理各种重复的一些方法
查看>>
MySQL replace函数替换字符串语句的用法(mysql字符串替换)
查看>>
mysql replace用法
查看>>
Mysql Row_Format 参数讲解
查看>>
mysql select, from ,join ,on ,where groupby,having ,order by limit的执行顺序和书写顺序
查看>>
MySQL Server 5.5安装记录
查看>>
mysql server has gone away
查看>>
mysql skip-grant-tables_MySQL root用户忘记密码怎么办?修改密码方法:skip-grant-tables
查看>>