博客
关于我
springboot整合Shiro
阅读量:660 次
发布时间:2019-03-15

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

Apache Shiro与Spring Boot集成实践指南

1.1 Shiro的三大核心概念

1.1.1 Subject

Subject是用户代表,任何与应用交互的主体都可视为Subject,包括用户、爬虫、机器人等。它与SecurityManager保持关联,所有安全交互都通过SecurityManager处理。

1.1.2 SecurityManager

作为Shiro的核心,SecurityManager管理所有Subject的安全交互,承担身份验证、权限验证等核心任务,类似于Spring MVC中的DispatcherServlet。

1.1.3 Realm

Realm是Shiro获取安全数据的源,用来从数据库或其他数据源获取用户的认证信息和权限。它类似于数据源,又类似于Spring中的DataSources。

2 Shiro的核心功能

2.1身份认证

通过验证用户凭证,确认用户身份的合法性。

2.2权限验证

确认已认证用户对特定资源的访问权限。

2.3会话管理

维护用户在应用中的会话信息,支持多种环境的会话管理。

2.4数据加密

保障敏感数据的安全性,例如密码加密存储。

2.5缓存机制

缓存用户信息等常用数据,提升应用性能。

2.6并发安全

支持多线程环境下的安全交互,确保多个线程间的权限传播。

3 Spring Boot整合Shiro

3.1导入依赖

org.apache.shiro
shiro-spring
1.7.1

3.2配置javaConfig

配置ShiroFilterFactoryBean、DefaultWebSecurityManager和Realm,通过注解方式管理相关Bean的生命周期。

3.3拦截器分类

dest NJ、campusservices、noSession等主要拦截器类别。

3.4javaConfig示例

@Configurationpublic class ShiroConfig {    @Bean    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Autowired DefaultWebSecurityManager securityManager) {        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();        filterFactoryBean.setSecurityManager(securityManager);        Map
filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/user/add", "authc"); filterChainDefinitionMap.put("/user/update", "authc"); filterChainDefinitionMap.put("/user/*", "authc"); filterChainDefinitionMap.put("/logout", "logout"); filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); filterFactoryBean.setLoginUrl("/toLogin"); filterFactoryBean.setUnauthorizedUrl("/unauth"); return filterFactoryBean; } @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(@Autowired UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userRealm); return securityManager; } @Bean public UserRealm userRealm() { return new UserRealm(); }}

3.5 Realm实现

public class UserRealm extends AuthorizingRealm {    @Autowired    private UserService userService;    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();        Subject currentUser = SecurityUtils.getSubject();        String username = currentUser.getPrincipal().toString();        User user = userService.getByUsername(username);        if (!StringUtils.isBlank(user.getPerm())) {            String[] perms = user.getPerm().split(",");            List
permList = new ArrayList<>(); Collections.addAll(permList, perms); authorizationInfo.addStringPermissions(permList); } return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken wpToken = (UsernamePasswordToken) token; String username = wpToken.getUsername(); User user = userService.getByUsername(username); if (user == null) { throw new UnknownAccountException(username); } return new SimpleAuthenticationInfo(username, user.getPassword(), ""); }}

3.6Controller实现

@Controllerpublic class MyController {    @RequestMapping("/toLogin")    public String toLogin() {        return "login";    }    @RequestMapping({"/", "/index"})    public String toIndex(Model model) {        model.addAttribute("msg", "Hello,Shiro");        return "index";    }    @RequestMapping("/user/add")    public String addUser() {        return "user/add";    }    @RequestMapping("/user/update")    public String updateUser() {        return "user/update";    }    @PostMapping("/login")    public String login(String username, String password, Model model) {        UsernamePasswordToken token = new UsernamePasswordToken(username, password);        Subject currentUser = SecurityUtils.getSubject();        try {            currentUser.login(token);            Session session = currentUser.getSession();            session.setAttribute("username", username);            return "index";        } catch (UnknownAccountException uae) {            model.addAttribute("msg", token.getPrincipal() + "用户名不匹配");            return "login";        } catch (IncorrectCredentialsException ice) {            model.addAttribute("msg", token.getPrincipal() + "密码错误");            return "login";        }    }    @ResponseBody    @RequestMapping("/unauth")    public String unAuth() {        return "未经授权";    }    @RequestMapping("/logout")    public String logout() {        return "/login";    }}

4 Shiro的"记住我"功能实现

通过配置RememberMe cookie,实现用户自动登录功能。

5 Shiro与Thymeleaf的整合

5.1依赖管理

com.github.theborakompanioni
thymeleaf-extras-shiro
2.0.0

5.2页面命名空间

        
管理员界面
具有更新权限的用户可以访问

6 实际案例

配置完成后,依次访问各资源,观察Shiro的拦截和授权效果,验证配置是否正确。

通过以上步骤,你可以完成Spring Boot与Shiro的成功集成,实现用户认证、权限管理和记住我等功能,同时结合Thymeleaf实现动态页面展示。

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

你可能感兴趣的文章
nginx配置一、二级域名、多域名对应(api接口、前端网站、后台管理网站)
查看>>
Nginx配置代理解决本地html进行ajax请求接口跨域问题
查看>>
nginx配置全解
查看>>
Nginx配置参数中文说明
查看>>
nginx配置域名和ip同时访问、开放多端口
查看>>
Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
查看>>
Nginx配置如何一键生成
查看>>
Nginx配置实例-负载均衡实例:平均访问多台服务器
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Nginx配置负载均衡到后台网关集群
查看>>
ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
查看>>
NHibernate学习[1]
查看>>
NHibernate异常:No persister for的解决办法
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
查看>>