springboot+thymeleaf+shiro标签的实例

目录
  • 1、pom中加入依赖
  • 2、用户-角色-权限的表关系
  • 3、编写shiro核心类
  • 4、登录控制器
  • 5、thymeleaf页面权限控制
  • 6、标签说明

1、pom中加入依赖

	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
			<version>1.5.6.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf -->
		<dependency>
			<groupId>org.thymeleaf</groupId>
			<artifactId>thymeleaf</artifactId>
			<version>${thymeleaf.version}</version>
		</dependency>
        <!-- shiro安全框架 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.4.0</version>
		</dependency>
		<!--thymeleaf-shiro-extras-->
		<dependency>
			<groupId>com.github.theborakompanioni</groupId>
			<artifactId>thymeleaf-extras-shiro</artifactId>
			<version>1.2.1</version>
		</dependency>

2、用户-角色-权限的表关系

//用户表
public class User {
    private Integer userId;
    private String userName;
    private Set<Role> roles = new HashSet<>();
}
//角色表
public class User {
    private Integer id;
    private String role;
    private Set<Module> modules = new HashSet<>();
    private Set<User> users = new HashSet<>();
}
//权限表
public class Module {
    private Integer mid;
    private String mname;
    private Set<Role> roles = new HashSet<>();
}

//用户查询
<resultMap id="BaseResultMap" type="com.lanyu.common.model.User" >
    <id column="user_id" property="userId" jdbcType="INTEGER" />
    <result column="user_name" property="userName" jdbcType="VARCHAR" />
    <!-- 多对多关联映射:collection -->
    <collection property="roles" ofType="Role">
      <id property="id" column="c_id" />
      <result property="role" column="role" />
      <collection property="modules" ofType="Module">
        <id property="mid" column="mid"/>
        <result property="mname" column="mname"/>
      </collection>
    </collection>
  </resultMap>

//查询用户信息,返回结果会自动分组,得到用户信息
  <select id="selectByPhone" resultMap="BaseResultMap" parameterType="java.lang.String" >
    SELECT
	  u.*, r.*, m.*
    FROM
        sys_user u
    INNER JOIN sys_user_role ur ON ur.userId = u.user_id
    INNER JOIN sys_role r ON r.rid = ur.roleid
    INNER JOIN sys_role_module mr ON mr.rid = r.rid
    INNER JOIN sys_module m ON mr.mid = m.mid
    WHERE
	  u.user_name=#{username} or u.phone=#{username};
  </select>

3、编写shiro核心类

@Configuration
public class ShiroConfiguration {

    //用于thymeleaf模板使用shiro标签
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
    @Bean(name="shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);
        //配置登录的url和登录成功的url
        bean.setLoginUrl("/loginpage");
        bean.setSuccessUrl("/indexpage");
        //配置访问权限
        LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();
//        filterChainDefinitionMap.put("/loginpage*", "anon"); //表示可以匿名访问
        filterChainDefinitionMap.put("/admin/*", "authc");//表示需要认证才可以访问
        filterChainDefinitionMap.put("/logout*","anon");
        filterChainDefinitionMap.put("/img/**","anon");
        filterChainDefinitionMap.put("/js/**","anon");
        filterChainDefinitionMap.put("/css/**","anon");
        filterChainDefinitionMap.put("/fomts/**","anon");
        filterChainDefinitionMap.put("/**", "anon");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }
    //配置核心安全事务管理器
    @Bean(name="securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
        System.err.println("--------------shiro已经加载----------------");
        DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
        manager.setRealm(authRealm);
        return manager;
    }
    //配置自定义的权限登录器
    @Bean(name="authRealm")
    public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
        AuthRealm authRealm=new AuthRealm();
        authRealm.setCredentialsMatcher(matcher);
        return authRealm;
    }
    //配置自定义的密码比较器
    @Bean(name="credentialsMatcher")
    public CredentialsMatcher credentialsMatcher() {
        return new CredentialsMatcher();
    }
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) {
        AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(manager);
        return advisor;
    }
}
— - - -- - -- - -- - -- - - -- - - - --
public class AuthRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    //认证.登录
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken utoken=(UsernamePasswordToken) token;//获取用户输入的token
        String username = utoken.getUsername();
        User user = userService.selectByPhone(username);
        return new SimpleAuthenticationInfo(user, user.getPassword(),this.getClass().getName());//放入shiro.调用CredentialsMatcher检验密码
    }
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        User user=(User) principal.fromRealm(this.getClass().getName()).iterator().next();//获取session中的用户
        List<String> permissions=new ArrayList<>();
        Set<Role> roles = user.getRoleList();
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        List<String> listrole = new ArrayList<>();
        if(roles.size()>0) {
            for(Role role : roles) {
                if(!listrole.contains(role.getRole())){
                    listrole.add(role.getRole());
                }
                Set<Module> modules = role.getModules();
                if(modules.size()>0) {
                    for(Module module : modules) {
                        permissions.add(module.getMname());
                    }
                }
            }
        }
        info.addRoles(listrole);                       //将角色放入shiro中.
    info.addStringPermissions(permissions);         //将权限放入shiro中.
        return info;
    }
}
//自定义密码比较器
public class CredentialsMatcher extends SimpleCredentialsMatcher {
    private  Logger logger = Logger.getLogger(CredentialsMatcher.class);
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        UsernamePasswordToken utoken=(UsernamePasswordToken) token;
        //所需加密的参数  即  用户输入的密码
        String source = String.valueOf(utoken.getPassword());
        //[盐] 一般为用户名 或 随机数
        String salt = utoken.getUsername();
        //加密次数
        int hashIterations = 50;
        SimpleHash sh = new SimpleHash("md5", source, salt, hashIterations);
        String Strsh =sh.toHex();
        //打印最终结果
        logger.info("正确密码为:"+Strsh);
        //获得数据库中的密码
        String dbPassword= (String) getCredentials(info);
        logger.info("数据库密码为:"+dbPassword);
        //进行密码的比对
        return this.equals(Strsh, dbPassword);
    }
}

4、登录控制器

    @RequestMapping("/loginUser")
    public String loginUser(String username,String password,HttpSession session) {
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);
        Subject subject = SecurityUtils.getSubject();
        Map map=new HashMap();
        try {
            subject.login(usernamePasswordToken);   //完成登录
            User user=(User) subject.getPrincipal();
            session.setAttribute("user", user);
            return "index";
        } catch (IncorrectCredentialsException e) {
            map.put("msg", "密码错误");
        } catch (LockedAccountException e) {
            map.put("msg", "登录失败,该用户已被冻结");
        } catch (AuthenticationException e) {
            map.put("msg", "该用户不存在");
        } catch (Exception e) {
            return "login";//返回登录页面
        }
        return map.toString();
    }

5、thymeleaf页面权限控制

<html lang="zh_CN" xmlns:th="http://www.thymeleaf.org"
	  xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

//作为属性控制
<button  type="button" shiro:authenticated="true" class="btn btn-outline btn-default">
	<i class="glyphicon glyphicon-plus" aria-hidden="true"></i>
</button>
//作为标签
<shiro:hasRole name="admin">
	<button type="button" class="btn btn-outline btn-default">
		<i class="glyphicon glyphicon-heart" aria-hidden="true"></i>
	</button>
</shiro:hasRole>

6、标签说明

guest标签
  <shiro:guest>
  </shiro:guest>
  用户没有身份验证时显示相应信息,即游客访问信息。
user标签
  <shiro:user>  
  </shiro:user>
  用户已经身份验证/记住我登录后显示相应的信息。
authenticated标签
  <shiro:authenticated>  
  </shiro:authenticated>
  用户已经身份验证通过,即Subject.login登录成功,不是记住我登录的。
notAuthenticated标签
  <shiro:notAuthenticated>
  
  </shiro:notAuthenticated>
  用户已经身份验证通过,即没有调用Subject.login进行登录,包括记住我自动登录的也属于未进行身份验证。
principal标签
  <shiro: principal/>
  
  <shiro:principal property="username"/>
  相当于((User)Subject.getPrincipals()).getUsername()。
lacksPermission标签
  <shiro:lacksPermission name="org:create">
 
  </shiro:lacksPermission>
  如果当前Subject没有权限将显示body体内容。
hasRole标签
  <shiro:hasRole name="admin">  
  </shiro:hasRole>
  如果当前Subject有角色将显示body体内容。
hasAnyRoles标签
  <shiro:hasAnyRoles name="admin,user">
   
  </shiro:hasAnyRoles>
  如果当前Subject有任意一个角色(或的关系)将显示body体内容。
lacksRole标签
  <shiro:lacksRole name="abc">  
  </shiro:lacksRole>
  如果当前Subject没有角色将显示body体内容。
hasPermission标签
  <shiro:hasPermission name="user:create">  
  </shiro:hasPermission>
  如果当前Subject有权限将显示body体内容

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot中的Thymeleaf用法

    Thymeleaf Thymeleaf是最近SpringBoot推荐支持的模板框架,官网在thymeleaf.org这里. 我们为什么要用Thymeleaf来作为模板引擎呢?官网给了我们一个非常令人信服的解释: Thymeleaf is a modern server-side Java template engine for both web and standalone environments.> 基本写法就像下面这样: <table> <thead> <tr&g

  • Spring Boot 整合 Shiro+Thymeleaf过程解析

    这篇文章主要介绍了Spring Boot 整合 Shiro+Thymeleaf过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.导包 <!-- springboot 与 shiro 的集成--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <

  • springboot整合shiro之thymeleaf使用shiro标签的方法

    thymeleaf介绍 简单说, Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP .相较与其他的模板引擎,它有如下三个极吸引人的特点: 1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果.这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式.浏览器解释 html 时会忽略未定义的标签属性,所以 t

  • springboot+thymeleaf+shiro标签的实例

    目录 1.pom中加入依赖 2.用户-角色-权限的表关系 3.编写shiro核心类 4.登录控制器 5.thymeleaf页面权限控制 6.标签说明 1.pom中加入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>1.5.6.RELEAS

  • springboot 在ftl页面上使用shiro标签的实例代码

    1.首先第一步导入依赖 <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>1.2.1</version> </dependency> 2.在配置shiro权限的方法内加入 @Bean public ShiroDialect sh

  • SpringBoot使用Thymeleaf自定义标签的实例代码

    此篇文章内容仅限于 描述springboot与 thy 自定义标签的说明,所以你在看之前,请先会使用springboot和thymeleaf!! 之前写过一篇是springMVC与thymeleaf 的自定义标签(属于自定义方言的属性一块,类似thy的th:if和th:text等)文章,如果你想了解,以下是地址: 点击>>Thymeleaf3.0自定义标签属性 这篇例子可以实现你的分页标签实现等功能,不会讲一堆的废话和底层的原理(自行百度),属于快速上手教程,请认真看以下内容! PS: 请允许

  • Springboot整合Shiro的代码实例

    这篇文章主要介绍了Springboot整合Shiro的代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.导入依赖 <!--shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</versio

  • springboot返回modelandview页面的实例

    1.添加依赖 这个应该是web项目相关的jar <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- jstl JSP标准标签库 --> <dependency> <groupId>javax.servle

  • Java安全框架——Shiro的使用详解(附springboot整合Shiro的demo)

    Shiro简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理 三个核心组件:Subject, SecurityManager 和 Realms Subject代表了当前用户的安全操作 SecurityManager管理所有用户的安全操作,是Shiro框架的核心,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务. Realm充当了Shiro与应用安全数据间的"桥梁"或者"连接器&q

  • SpringBoot整合Shiro实现权限控制的代码实现

    1.SpringBoot整合Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 1.1.shiro简介 shiro有个核心组件,分别为Subject.SecurityManager和Realms Subject:相当于当前操作的"用户",这个用户不一定是一个具体的人,是一个抽象的概念,表明的是和当前程序进行交互的任何东西,例如爬虫.脚本.等等.所有的Subject都绑定到SecurityManager上,与 Subject 的所

  • springboot整合shiro的过程详解

    目录 什么是 Shiro Shiro 架构 Shiro 架构图 Shiro 工作原理 Shiro 详细架构图 springboot 整合 shiro springboot 整合 shiro 思路 项目搭建 主要依赖 数据库表设计 实体类 自定义 Realm shiro 的配置类 ShiroFilterFactoryBean 过滤器链配置中的 url 匹配规则 ShiroFilterFactoryBean 过滤器 ShiroFilterFactoryBean 过滤器分类 前端页面 登录页面 log

  • springboot整合shiro实现记住我功能

    前言 上一篇文章我们完成了在 thymeleaf 模板引擎中使用 shiro 标签,也就是根据不同的用户身份信息,前端页面来显示不同的页面内容.本篇文章我们来完成在登录页面的记住我的功能 springboot 整合 shiro 之实现记住我 项目依然使用 springboot整合shiro这个项目,稍稍改动即可完成记住我的功能 配置类 ShiroConfig 完整的代码如下 @Configuration public class ShiroConfig { /** * 安全管理器 * * @pa

随机推荐