SpringBoot整合shiro从初恋到失恋

栏目: Java · 发布时间: 5年前

内容简介:另外三个跳转页面就不贴出来了,panpan账号登录可以查看和删除,用xiaoli账号登录则只有查看而没有删除的权限,代码见下面,sql文件在resources包下

建个项目或者模块,目录结构如下

SpringBoot整合shiro从初恋到失恋

在pom.xml中加入shiro依赖,其他依赖自行添加(lombok,jpa,mybatis,web,thymeleaf等)

<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>

application.properties中的配置

##端口号
server.port=8888
##数据库配置
##数据库地址
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?characterEncoding=utf8&useSSL=false\
  &serverTimezone=GMT%2B8
##数据库用户名
spring.datasource.username=root
##数据库密码
spring.datasource.password=Panbing936@
##数据库驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
##validate  加载hibernate时,验证创建数据库表结构
##create   每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
##create-drop        加载hibernate时创建,退出是删除表结构
##update                 加载hibernate自动更新数据库结构
##validate 启动时验证表的结构,不会创建表
##none  启动时不做任何操作
spring.jpa.hibernate.ddl-auto=update
##控制台打印sql
spring.jpa.show-sql=true
# 建议在开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false
##去除thymeleaf的html严格校验
spring.thymeleaf.mode=LEGACYHTML5
#没下面这行配置就会报这个错误
#Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect

实体类SysMenu.java中的代码

@Entity
@Data
public class SysMenu implements Serializable {

    @Id
    @GeneratedValue
    private Integer menuId;
    private String menuName;

    @ManyToMany
    @JoinTable(name = "SysRoleMenu", joinColumns = {@JoinColumn(name = "menuId")}, inverseJoinColumns = {@JoinColumn(name = "roleId")})
    private List<SysRole> roleList;
}

实体类SysRole.java中的代码

@Entity
@Data
public class SysRole implements Serializable {

    @Id
    @GeneratedValue
    private Integer roleId;

    private String roleName;

    //多对多关系
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "SysRoleMenu", joinColumns = {@JoinColumn(name = "roleId")}, inverseJoinColumns = {@JoinColumn(name = "menuId")})
    private List<SysMenu> menuList;

    //多对多关系
    @ManyToMany
    @JoinTable(name = "SysUserRole", joinColumns = {@JoinColumn(name = "roleId")}, inverseJoinColumns = {@JoinColumn(name = "userId")})
    private List<SysUser> userList;// 一个角色对应多个用户
}

实体类SysUser.java中的代码

@Entity
@Data
public class SysUser implements Serializable {

    @Id
    @GeneratedValue
    private Integer userId;
    @NotEmpty
    private String userName;
    @NotEmpty
    private String passWord;

    //多对多关系
    @ManyToMany(fetch = FetchType.EAGER)
    //急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载
    //FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载
    @JoinTable(name = "SysUserRole", joinColumns = {@JoinColumn(name = "userId")},
            inverseJoinColumns = {@JoinColumn(name = "roleId")})
    private List<SysRole> roleList;// 一个用户具有多个角色

}

接口UserRepository.java中的代码

public interface UserRepository extends CrudRepository<SysUser,Long> {

    SysUser findByUserName(String username);
}

下面的代码才是shiro相关的

MyshiroRealm.java

public class MyShiroRealm extends AuthorizingRealm {

    @Resource
    private UserRepository userRepository;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        SysUser userInfo  = (SysUser)principals.getPrimaryPrincipal();
        for(SysRole role:userInfo.getRoleList()){
            authorizationInfo.addRole(role.getRoleName());
            for(SysMenu menu:role.getMenuList()){
                authorizationInfo.addStringPermission(menu.getMenuName());
            }
        }
        return authorizationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        //获得当前用户的用户名
        String username = (String)token.getPrincipal();
        System.out.println(token.getCredentials());
        //根据用户名找到对象
        //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
        SysUser userInfo = userRepository.findByUserName(username);
        if(userInfo == null){
            return null;
        }
        //这里会去校验密码是否正确
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                userInfo, //用户名
                userInfo.getPassWord(),//密码
                getName()
        );
        return authenticationInfo;
    }
}

ShiroConfig.java

@Configuration
public class ShiroConfig {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        logger.info("启动shiroFilter--时间是:" + new Date());
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //shiro拦截器
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->

        // 配置不被拦截的资源及链接
        filterChainDefinitionMap.put("/static/**", "anon");
        // 退出过滤器
        filterChainDefinitionMap.put("/logout", "logout");

        //配置需要认证权限的
        filterChainDefinitionMap.put("/**", "authc");
        // 如果不设置默认会自动寻找Web工程根目录下的"/login"页面,即本文使用的login.html
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");

        //未授权界面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    //自定义身份认证Realm(包含用户名密码校验,权限校验等)
    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }


    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //开启shiro aop注解支持,不开启的话权限验证就会失效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    //配置异常处理,不配置的话没有权限后台报错,前台不会跳转到403页面
    @Bean(name="simpleMappingExceptionResolver")
    public SimpleMappingExceptionResolver
    createSimpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
        mappings.setProperty("UnauthorizedException","403");
        simpleMappingExceptionResolver.setExceptionMappings(mappings);  // None by default
        simpleMappingExceptionResolver.setDefaultErrorView("error");    // No default
        simpleMappingExceptionResolver.setExceptionAttribute("ex");     // Default is "exception"
        return simpleMappingExceptionResolver;
    }
}

thymeleaf的页面代码

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
index
<br/>
<form th:action="@{/logout}" method="post">
    <p><input type="submit" value="重新登录"/></p>
</form>
<form th:action="@{/select}" method="get">
    <p><input type="submit" value="查看"/></p>
</form>
<form th:action="@{/delete}" method="get">
    <p><input type="submit" value="删除"/></p>
</form>
</body>
</html>

login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
错误信息:<h4 th:text="${msg}"></h4>
<form action="" method="post">
    <p>账号:<input type="text" name="username" value="dalaoyang"/></p>
    <p>密码:<input type="text" name="password" value="123"/></p>
    <p><input type="submit" value="登录"/></p>
</form>
</body>
</html>

另外三个跳转页面就不贴出来了,panpan账号登录可以查看和删除,用xiaoli账号登录则只有查看而没有删除的权限,代码见下面,sql文件在resources包下


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

机械设计实践

机械设计实践

村洋太郎(日) / 王启义/等 / 机械工业出版社 / 1998-08 / 36.00

本书记述了各种设计过程的思考方法和具体作法以及必要的知识和具 体数据。介绍了设计中要决定的内容和相应的制约条件。如功能、机构、 构造、形状、力和强度、尺寸加工工艺、工具、材料、机械要素等。最后 介绍了具体设计实例。本书的目的在于即使不看其他的书和参考书就能设 计出所需要的具体机械。 本书供从事机械设计的有关技术人员及大专院校相关专业的师生使 用。一起来看看 《机械设计实践》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具