spring boot+Shiro+mybatis框架环境搭建

本人也是第一次刚搭建shiro框架,参考一些资料和博客,进行搭建,有啥不足之处或改进的地方希望各位指出。

先建好springboot项目,进行测试

第一步,引入依赖

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
        <!--没有此依赖shiro注解权限会失效-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-logging</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-freemarker</artifactId>
		</dependency>
		<!--lombok插件使用依赖-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<!--mybatis plus依赖-->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatisplus-spring-boot-starter</artifactId>
			<version>${mybatisplus-spring-boot-starter.version}</version>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus</artifactId>
			<version>${mybatisplus.version}</version>
		</dependency>
		<!--数据源相关-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>${druid.version}</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<!--shiro依赖-->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>${shiro-spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<!--热部署-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>

第二部,配置application.properties文件

server.port=8080
# 数据库访问配置
# 主数据源,默认的
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shrio?Unicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root


#集成Freemark
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
spring.freemarker.request-context-attribute=request
spring.freemarker.allow-session-override=true
#Mybatis配置
mybatis-plus.mapper-locations=classpath:mappers/*.xml
#mybatis-plus的model包
mybatis-plus.typeAliasesPackage=com.joecy.entity
#global-config:
#主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
#id-type: 2
mybatis-plus.global-config.id-type=0
#驼峰式命名映射
mybatis-plus.global-config.db-column-underline=true

第三步,项目Action启动类权限访问和拦截器

    @GetMapping(value = "/login")
    public String login(){
        return "login";
    }

    @PostMapping(value = "/user_login")
    public String login(@RequestParam String username, @RequestParam String password, Model model){
        try {
            System.out.println(username+"          "+password);
            model.addAttribute("username", username);
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();
            //完成登录
            subject.login(usernamePasswordToken);
            return "redirect:/index";
        } catch (Exception e) {
            String ex = e.getClass().getName();
            if (ex != null) {
                if (UnknownAccountException.class.getName().equals(ex)) {
                    System.out.println("用户名不存在");
                } else if (IncorrectCredentialsException.class.getName().equals(ex)) {
                    System.out.println("账户或密码错误");
                } else {
                    System.out.println("未知错误");
                }
            }
            //返回登录页面
            return "login";
        }
    }

    @ResponseBody
    @GetMapping(value = "/index")
    public String index(){
        return "welcome";
    }


    //注解的使用
    //管理员角色
    @ResponseBody
    @RequiresRoles("admin")
    @RequestMapping(value = "/role/admin")
    public String roleAdmin(){
        return "I am admin";
    }
    //只拥有添加权限
    @ResponseBody
    @RequiresPermissions("add")
    @RequestMapping(value = "/permission/add")
    public String Permission(){
        return "I have permission add";
    }

第四步,建立实体类,我只列出一个,剩下看自己需求建立

@Data
public class SecRole extends Model<SecRole> {

    @TableId
    private Integer id;
    private String name;
    @TableField(exist = false)
    private List<SecPermission> permissions;

    @Override
    protected Serializable pkVal() {
        return this.id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<SecPermission> getPermissions() {
        return permissions;
    }

    public void setPermissions(List<SecPermission> permissions) {
        this.permissions = permissions;
    }
}

第五步,建立MyShiroRealm和ShiroConfig2个类

public class MyShiroRealm extends AuthorizingRealm {

    //角色权限和对应权限添加
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        System.out.println(principalCollection.getPrimaryPrincipal());
        SecUser user= (SecUser) principalCollection.getPrimaryPrincipal();
        //保存所有角色名
        Set<String> allRoles = new HashSet<>();
        System.out.println("当前角色所有名字 :"+allRoles.size());
        //保存所有权限名
        Set<String> allPermissions = new HashSet<>();
        System.out.println("当前权限所有名字 :"+allRoles.size());
        //查询对应角色
        List<SecUserRole> secUserRoles = new SecUserRole().selectList(new EntityWrapper().eq("user_id", user.getId()));
        for (SecUserRole userRole:secUserRoles) {
            SecRole role = new SecRole();
            role.setId(userRole.getRoleId());
            role = role.selectById();
            allRoles.add(role.getName());

            //查询所有权限
            List<SecPermission> permissions = new ArrayList<>();
            List<SecRolePermission> rolePermissions = new SecRolePermission().selectList(new EntityWrapper().eq("role_id", role.getId()));
            for (SecRolePermission rolePermission:rolePermissions) {
                SecPermission permission = new SecPermission();
                permission.setId(rolePermission.getPermissionId());
                permission = permission.selectById();
                System.out.println(permission.getName());
                allPermissions.add(permission.getName());
            }
        }

        //添加角色
        simpleAuthorizationInfo.addRoles(allRoles);
        simpleAuthorizationInfo.addStringPermissions(allPermissions);
        user.getRoles();

        System.out.println(user+"      "+allRoles);

        return simpleAuthorizationInfo;
    }

    //用户认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 1、登录认证的方法需要先执行,需要用他来判断登录的用户信息是否合法
        String username = (String) token.getPrincipal();    // 取得用户名
        // 需要通过用户名取得用户的完整信息,利用业务层操作
        System.out.println("当前角色名字 :"+username);
        SecUser user = null;
        try {
            user = new SecUser().selectOne(new EntityWrapper().eq("username",username));
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (user == null) {
            throw new UnknownAccountException("该用户名称不存在!");
        } else {    // 进行密码的验证处理
            String password =new String((char[]) token.getCredentials());
            // 将数据库中的密码与输入的密码进行比较,这样就可以确定当前用户是否可以正常登录
            if (user.getPassword().equals(password)) {    // 密码正确

                AuthenticationInfo auth = new SimpleAuthenticationInfo(user, password, "memberRealm");
                return auth;
            } else {
                throw new IncorrectCredentialsException("密码错误!");
            }
        }
    }
}
@Configuration
public class ShiroConfig {

    //将自己的验证方式加入容器
    @Bean
    public MyShiroRealm myShiroRealm() {
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }

    //权限管理,配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //Filter工厂,设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        System.out.println("登录-------------跳转");
        shiroFilterFactoryBean.setSuccessUrl("/index");

        // 权限控制map.
        LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();
        filterChainDefinitionMap.put("/css/**", "anon"); //表示可以匿名访问
        filterChainDefinitionMap.put("/js/**", "anon"); //表示可以匿名访问
        filterChainDefinitionMap.put("/img/**", "anon"); //表示可以匿名访问
        filterChainDefinitionMap.put("/font/**", "anon"); //表示可以匿名访问
        filterChainDefinitionMap.put("/images/**", "anon"); //表示可以匿名访问
        filterChainDefinitionMap.put("/login", "anon"); //表示可以匿名访问
        filterChainDefinitionMap.put("/user_login", "anon");
        filterChainDefinitionMap.put("/logout*","logout");
        filterChainDefinitionMap.put("/error","anon");
        filterChainDefinitionMap.put("/**","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    //加入注解的使用,不加入这个注解不生效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        System.out.println("开启了shiro注解功能");
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

mapper中代码如下


@Mapper
public interface SecRoleMapper extends BaseMapper<SecRole> {
}

和实体类一样,之列了一个,剩下自己补齐。

最后写个登陆测试界面调到user_login方法进行测试就行了。我的表结构如下:

注意,name的值 记得@Requires注解里的值一样咯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值