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

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

Spring Boot整合Shiro

Spring Boot整合Shiro的过程与SSM项目中类似,但在配置文件管理上更加简化。以下将详细介绍Spring Boot项目中Shiro的配置与使用方法。


项目结构

1.1 访问流程

项目结构图展示了项目的主要模块分布,访问流程图展示了用户从登录到资源访问的完整过程。


项目内容

1.3 配置类及POM文件

1.3.1 项目启动类

@SpringBootApplication@MapperScan("com.fyx.dao")public class Day0408SpringbootApplication {    public static void main(String[] args) {        SpringApplication.run(Day0408SpringbootApplication.class, args);    }}

1.3.2 POM文件

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.baomidou
mybatis-plus-boot-starter
3.4.2
com.alibaba
druid-spring-boot-starter
1.1.14

1.3.3 application.properties

# 数据源配置spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driversspring.datasource.druid.url=jdbc:mysql:///shirosspring.datasource.druid.username=rootsspring.datasource.druid.password=123@qwe

1.3.4 Shiro配置类

@Configurationpublic class ShiroConfig {    @Bean("securityManager")    public DefaultWebSecurityManager securityManager(Realm myRealm) {        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();        securityManager.setRealm(myRealm);        return securityManager;    }    @Bean("myRealm")    public Realm getRealm(CredentialsMatcher credentialsMatcher) {        MyRealm myRealm = new MyRealm();        myRealm.setCredentialsMatcher(credentialsMatcher);        return myRealm;    }    @Bean("credentialsMatcher")    public CredentialsMatcher getCredentialsMatcher() {        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();        credentialsMatcher.setHashIterations(1024);        credentialsMatcher.setHashAlgorithmName("MD5");        return credentialsMatcher;    }    @Bean("shiroFilter")    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; } @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setName("shiroFilter"); filterRegistrationBean.setFilter(new DelegatingFilterProxy()); filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } @Bean public ShiroDialect shiroDialect() { return new ShiroDialect(); }}

1.4 HTML文件

1.4.1 login.html

    
Login Page
账号:
密码:

1.4.2 success.html

    
Success Page

欢迎来到XXX班

查询所有用户
修改用户
删除用户
添加用户
导出用户

1.4.3 un.html

    
无权访问

无权访问


后端类文件

1.5 DAO层

1.5.1 UserDao

public interface UserDao extends BaseMapper
{ List
findPermissionByUserid(Integer userid);}

1.5.2 PermissionDao

public interface PermissionDao {    List
findAllPermissionByUserId(Integer userid);}

1.6 Entity层

@Data@AllArgsConstructor@NoArgsConstructorpublic class User {    private Integer userid;    private String username;    private String userpwd;    private String sex;    private String address;    private String salt;}

1.7 Service层

1.7.1 UserService

public interface UserService {    User selectByUsername(String username);}

1.7.2 UserServiceImpl

@Servicepublic class UserServiceImpl implements UserService {    @Resource    private UserDao userDao;    @Override    public User selectByUsername(String username) {        QueryWrapper
wrapper = new QueryWrapper<>(); wrapper.eq("username", username); User user = userDao.selectOne(wrapper); return user; }}

1.8 Mapping文件

1.9 Controller层

1.9.1 PageController

@RestControllerpublic class PageController {    @GetMapping("/tologin")    public Result loginPage() {        return new Result(5002, "请先登录", null);    }}

1.9.2 LoginController

@RestControllerpublic class LoginController {    @PostMapping("login")    public Result login(String username, String userpwd) {        Subject subject = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(username, userpwd);        try {            subject.login(token);            return new Result(2000, "登录成功", subject.getPrincipal());        } catch (Exception e) {            return new Result(5000, "登录失败", null);        }    }}

1.9.3 UserController

@RestController@RequestMapping("user")public class UserController {    @GetMapping("query")    @RequiresPermissions("user:query")    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")    public String export() {        return "user:export";    }}

1.9.4 ExceptionController

@RestControllerAdvicepublic class ExceptionController {    @ExceptionHandler(value = AuthorizationException.class)    public Result unauthorizedException() {        return new Result(5001, "权限不足", null);    }}

1.9.5 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();        List
userIds = permissionService.findAllPermissionByUserId(user.getUserid()); if (userIds.size() > 0) { return new SimpleAuthorizationInfo(); for (String userId : userIds) { // 添加权限信息 } } return null; } @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()); return new SimpleAuthenticationInfo(user, user.getUserpwd(), bytes, this.getName()); } return null; }}

完全分离式架构

2.1 前后端分离

前后端完成分离,后端返回给访问者的是JSON数据。需要在以下三个地方改造返回JSON数据:

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

  • 2.2 返回数据格式

    创建返回的JSON数据格式的Result类:

    @Data@NoArgsConstructor@AllArgsConstructorpublic class Result {    private Integer code;    private String msg;    private Object data;}

    2.3 Controller改造

    @Controller改为@RestController,将@ControllerAdvice改为@RestControllerAdvice

    2.3.1 LoginController

    @RestControllerpublic class LoginController {    @PostMapping("login")    public Result login(String username, String userpwd) {        Subject subject = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(username, userpwd);        try {            subject.login(token);            return new Result(2000, "登录成功", subject.getPrincipal());        } catch (Exception e) {            return new Result(5000, "登录失败", null);        }    }}

    2.3.2 PageController

    @RestControllerpublic class PageController {    @GetMapping("/tologin")    public Result loginPage() {        return new Result(5002, "请先登录", null);    }}

    2.3.3 ExceptionController

    @RestControllerAdvicepublic class MyHandlerException {    @ExceptionHandler(value = UnauthorizedException.class)    public Result unauthorizedException() {        return new Result(5001, "权限不足", null);    }}

    测试

    测试部分需要注意以下几点:

  • 确保数据库连接配置正确
  • Shiro的FilterChainDefinitionMap配置正确
  • 权限注解@RequiresPermissions正确使用
  • 返回数据格式符合预期

  • 通过以上配置和实现,Spring Boot项目可以成功整合Shiro进行用户认证和权限管理。

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

    你可能感兴趣的文章
    Parameter ‘password‘ not found. Available parameters are [md5String, param1, username, param2]
    查看>>
    ParameterizedThreadStart task
    查看>>
    Paramiko exec_命令的实时输出
    查看>>
    Spring security之管理session
    查看>>
    paramiko模块
    查看>>
    param[:]=param-lr*param.grad/batch_size的理解
    查看>>
    spring mvc excludePathPatterns失效 如何解决spring拦截器失效 excludePathPatterns忽略失效 拦截器失效 spring免验证拦截器不起作用
    查看>>
    Spring Cloud 之注册中心 EurekaServerAutoConfiguration源码分析
    查看>>
    Parrot OS 6.2 重磅发布!推出全新 Docker 容器启动器
    查看>>
    Parrot OS 6.3 发布!全面提升安全性,新增先进工具,带来更高性能
    查看>>
    ParseChat应用源码ios版
    查看>>
    Part 2异常和错误
    查看>>
    Pascal Script
    查看>>
    Spring Boot集成Redis实现keyspace监听 | Spring Cloud 34
    查看>>
    Spring Boot中的自定义事件详解与实战
    查看>>
    Passport 密码模式
    查看>>
    Spring Boot(七十六):集成Redisson实现布隆过滤器(Bloom Filter)
    查看>>
    passwd命令限制用户密码到期时间
    查看>>
    Spring Boot 动态加载jar包,动态配置太强了!
    查看>>
    Spring @Async执行异步方法的简单使用
    查看>>