Shiro框架基本使用

一、创建maven项目,引入依赖

  
        
            org.apache.directory.studio
            org.apache.commons.codec
            1.8
        
        
        
            org.apache.shiro
            shiro-spring-boot-starter
            1.5.3
        
        
        
            org.slf4j
            jcl-over-slf4j
            runtime
        
        
            com.auth0
            java-jwt
            3.11.0
        
        
            io.jsonwebtoken
            jjwt
            0.9.1
        
        
            org.apache.logging.log4j
            log4j-core
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.projectlombok
            lombok
        
        
        
            org.mybatis
            mybatis
            3.5.2
        
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            
            2.1.1
        
        
            mysql
            mysql-connector-java
            runtime
            5.1.46
        
    


    
        
            
                src/main/java
                
                    **/*.*
                
            
            
                src/main/resources
                
                    **/*.*
                
            
        

        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

        这些依赖包括MySQL、mybatis和logf4j依赖,之后都会用到 

        这是最基础的 application.properties 配置

spring.main.allow-bean-definition-overriding= true
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/syslog?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
mybatis.configuration.mapUnderscoreToCamelCase=true

二、前期准备

        shrio登录的时候会用到用户的账号密码做登录判断需要创建数据库和实体映射文件,之所以不用shiro.ini是因为更好的理解shrio框架的使用,而不是为了糊弄。

        1、创建数据库用户表

Shiro框架基本使用_第1张图片

create table sys_user(id varchar(255),user_name varchar(255),password varchar(255),phone varchar(255),avatar varchar(255));

        2、创建实体类

package com.example.shiro_sys.entity;

import com.example.shiro_sys.util.BaseEntity;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class UserInfo{
    private String userName;
    private String password;
    private String phone;
}

        3、创建mapper和对应mybatis.xml文件

package com.example.shiro_sys.mapper;

import com.example.shiro_sys.entity.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface UserMapper {
    public void insert ();
    public UserInfo selectUserName (UserInfo userInfo);
}





    
        insert into sys_user(user_name)
        values (#{username})
    

    

        在spring启动类中添加注解扫描mapper.xml文件 

        @MapperScan("com.example.shiro_sys.mapper")

package com.example.shiro_sys;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
@MapperScan("com.example.shiro_sys.mapper")
public class ShiroSysApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShiroSysApplication.class, args);
    }

}

三、创建Shiro配置文件

        这是我的文件目录有config配置类,controller控制层,mapper和service层,最后还有些页面静态资源。

Shiro框架基本使用_第2张图片

         1、创建配置类SpringShiroConfig,此类主要将访问请求拦截和放行请求。

package com.example.shiro_sys.config;

import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;


@Configuration
public class SpringShiroConfig {
    //1.创建自定义realm
    @Bean
    public Realm getRealm() {
        CustomRealm customerRealm = new CustomRealm();
        return customerRealm;
    }

    //2.创建shiroFilter  //负责拦截所有请求
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //给filter设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //配置系统受限资源
        //配置系统公共资源
        Map map = new HashMap();
        map.put("/user/login", "anon");  // anon 设置为公共资源,放行要注意anon和authc的顺序
        map.put("/**", "authc");  //authc 请求这个资源需要认证和授权

        //默认认证界面路径
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //3.创建安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") Realm realm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //给安全管理器设置
        defaultWebSecurityManager.setRealm(realm);
        return defaultWebSecurityManager;
    }

}

         2、创建自定义Realm类,此类主要是创建凭证用于登录判断。

package com.example.shiro_sys.config;

import com.example.shiro_sys.entity.UserInfo;
import com.example.shiro_sys.mapper.UserMapper;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CustomRealm extends AuthorizingRealm {
    @Autowired
    private UserMapper userMapper;

    // 授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    // 认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取当前登录的主体
        String principal = (String) token.getPrincipal();
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName(principal);
        UserInfo user = userMapper.selectUserName(userInfo);

        // 模拟数据库返回的数据
        // 目前用户名为唯一标识
        if (user.getUserName().equals(principal)) {
            //用户名匹配成功后,将数据库查询到的用户密码存入上下文中,在调用subject.login(new UsernamePasswordToken(username,password));
            //时会将存入上下文中的密码作比对,这里用的密码凭证是密码,也可以存放动态验证码
            return new SimpleAuthenticationInfo(principal, user.getPassword(), this.getName());
        }
        return null;

    }

}

四、测试

        1、创建controller和静态访问页面

package com.example.shiro_sys.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("user")
public class UserController {
    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("login")
    public String login(String username,String password){
        System.out.println("~~~~~~login~~~~~");
        // 获取当前登录用户
        Subject subject = SecurityUtils.getSubject();

        try {
            // 执行登录操作
            subject.login(new UsernamePasswordToken(username,password));
            // 认证通过后直接跳转到index.jsp
            return "redirect:/index.html";
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户名错误");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误");
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 如果认证失败仍然回到登录页面
        return "redirect:/login.html";
    }

    @RequestMapping("logout")
    public String logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        // 退出后仍然会到登录页面
        return "redirect:/login.html";
    }

    public static void main(String[] args) {
        Md5Hash md5Hash03 = new Md5Hash("1234567","1q2w3e",1024);
        System.out.println(md5Hash03.toHex());
    }

}



    
    Title


登录

用户名:
密码 :



  
  Title


首页

退出用户

你可能感兴趣的:(java)