博客
关于我
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/

    你可能感兴趣的文章
    NFS网络文件系统
    查看>>
    nft文件传输_利用remoting实现文件传输-.NET教程,远程及网络应用
    查看>>
    NFV商用可行新华三vBRAS方案实践验证
    查看>>
    ng build --aot --prod生成文件报错
    查看>>
    ng 指令的自定义、使用
    查看>>
    nghttp3使用指南
    查看>>
    Nginx
    查看>>
    nginx + etcd 动态负载均衡实践(三)—— 基于nginx-upsync-module实现
    查看>>
    nginx + etcd 动态负载均衡实践(二)—— 组件安装
    查看>>
    nginx + etcd 动态负载均衡实践(四)—— 基于confd实现
    查看>>
    Nginx + Spring Boot 实现负载均衡
    查看>>
    Nginx + uWSGI + Flask + Vhost
    查看>>
    Nginx - Header详解
    查看>>
    Nginx - 反向代理、负载均衡、动静分离、底层原理(案例实战分析)
    查看>>
    nginx 1.24.0 安装nginx最新稳定版
    查看>>
    nginx 301 永久重定向
    查看>>
    nginx css,js合并插件,淘宝nginx合并js,css插件
    查看>>
    Nginx gateway集群和动态网关
    查看>>
    Nginx Location配置总结
    查看>>
    Nginx log文件写入失败?log文件权限设置问题
    查看>>