您当前的位置: 首页 >  spring

SpringBoot整合Shiro

梁云亮 发布时间:2020-09-05 21:59:09 ,浏览量:5

SpringBoot整合Shiro

SpringBoot整合Shiro编程步骤博客

环境搭建 第一步:创建项目,添加依赖

    org.springframework.boot
    spring-boot-starter-web


    org.springframework.boot
    spring-boot-starter-thymeleaf


    org.apache.shiro
    shiro-spring-boot-web-starter
    1.6.0



    org.apache.shiro
    shiro-all
    1.6.0



    org.slf4j
    jcl-over-slf4j
    1.7.30


    org.slf4j
    slf4j-log4j12
    1.7.30


    log4j
    log4j
    1.2.17


    org.projectlombok
    lombok
    1.18.12

第二步:编写log4j.properties
### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
第三步:自定义Realm
public class UserRealm extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("=======doGetAuthorizationInfo===============");
        return null;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("=========doGetAuthenticationInfo===============");
        return null;
    }
}
第四步:Shiro配置文件
@Configuration
public class ShiroConfig {
    //1.创建realm对象,使用自定义类
    @Bean(name = "userRealm")
    public UserRealm myShiroRealm() { //将自己的验证方式加入容器
        UserRealm userRealm = new UserRealm();
        return userRealm;
    }
    //2.创建DefaultWebSecurityManager
    @Bean(name = "dwSecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        //关联realm
        manager.setRealm(userRealm);
        return manager;
    }
    //3.创建ShiroFilterFactoryBean
    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("dwSecurityManager") DefaultWebSecurityManager manager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(manager);
        return bean;
    }
}
第五步:按下图所示创建网页:
  • add.html
DOCTYPE html>

    
        
        增加用户
    
    
        增加用户
    

  • update.html
DOCTYPE html>

    
        
        修改用户
    
    
        修改用户
    

  • index.html
DOCTYPE html>

    
        
        首页
    
    
        
        
        增加用户        
修改用户
    

第六步:创建数据库模拟类
public class DB {
    private static List users = new ArrayList();
    private static Map auths = new HashMap();
    static {
        users.add(new User(1001, "hc", "hc"));
        users.add(new User(1002, "zhangsan", "zhangsan"));
        users.add(new User(1003, "lisi", "lisi"));
        users.add(new User(1004, "wanger", "wanger"));
        auths.put(1001, new HashSet(Arrays.asList("user:add", "user:update")));
        auths.put(1002, new HashSet(Arrays.asList("user:add")));
        auths.put(1003, new HashSet(Arrays.asList("user:update")));
        auths.put(1004, new HashSet(Arrays.asList("user:add", "user:update")));
    }
    public static Set getAuths(Integer userId){
        return auths.get(userId);
    }
    public static User getUserByUsername(String username) {
        for (User user : users) {
            if (user.getUsername().equals(username)) {
                return user;
            }
        }
        return null;
    }
}
第七步:分发用户请求的控制器
@Controller
public class DispatchController {
    @RequestMapping("/index")
    public String index(Model model){
        model.addAttribute("msg","Hello,Shiro");
        return "index";
    }
    @RequestMapping("/login")
    public String login(){
        return "login";
    }
}
第八步:分发处理用户相关请求的控制器
@Controller
@RequestMapping("/user")
@Log4j
public class UserController {
    @RequestMapping("/add")
    public String add(Model model) {
        return "user/add";
    }
    @RequestMapping("/update")
    public String update(Model model) {
        return "user/update";
    }
}

部署项目运行,在index页面中单击”增加用户”或者“修改用户”超连接,结果都会直接打开对应的页面。

Shiro实现登录拦截 第一步:修改ShiroConfig中getShiroFilterFactoryBean方法,为其添加登录拦截的代码:
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("dwSecurityManager") DefaultWebSecurityManager manager) {
    ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
    bean.setSecurityManager(manager);
    //添加shiro的内置过滤器
    Map map = new LinkedHashMap();
    //拦截
    map.put("/user/add", "authc");
    map.put("/user/update", "authc");
//------------②
    bean.setFilterChainDefinitionMap(map);
    bean.setLoginUrl("/login");  //--------①
    //设置安全管理器
    return bean;
}

上面编号①处的login对应的是在templates目录的login.html页面,其代码如下:

DOCTYPE html>

    
        
        登录
    
    
        
        
        
           用户名: 
            密码:
            
        
    

部署项目运行,在index页面中单击”增加用户”或者“修改用户”超连接,结果都会直接打开登录页面。

Shiro实现登录认证 第一步:修改UserRealm.java中doGetAuthenticationInfo方法的代码如下:
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException{     
System.out.println("========doGetAuthenticationInfo=================");
    UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//模拟从数据库中获取用户名密码
    User user = DB.getUserByUsername(userToken.getUsername());
    if (null == user) { //用户不存在
        return null; //抛出异常UnknownAccountException
    }
    //用户登录成功,将用户信息保存在Shiro的session中 
SecurityUtils.getSubject().getSession()
.setAttribute("currentLoginedUser",user);
    //不能(不建议)自己做密码认证,系统会自己做
    // 第一个参数为完整用户信息,方便授权时查找用户的权限
    return new SimpleAuthenticationInfo(user, user.getUserpwd(), ""); 
}
第二步:修改UserController类,为其添加如下代码:
@PostMapping("/login")
public String login(String username, String userpwd, Model model) {
    //获取当前的用户
    Subject subject = SecurityUtils.getSubject();
    //封装用户的登录数据
    UsernamePasswordToken token = new UsernamePasswordToken(username, userpwd);
    try {
        subject.login(token);
        return "index"; //登录成功后打开首页
    } catch (UnknownAccountException e) { //用户名不存在
        model.addAttribute("msg", "用户名错误");
        log.info(e.getMessage());
        return "login";
    } catch (IncorrectCredentialsException e) { //用户名不存在
        model.addAttribute("msg", "密码错误");
        log.info(e.getMessage());
        return "login";
    }
}
Shiro请求授权实现 第一步:修改UserRealm.java中doGetAuthenticationInfo方法,在其中添加授权的代码如下:
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("dwSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    //设置安全管理器
    shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
    //添加shiro的内置过滤器
    Map map = new LinkedHashMap();
    //拦截
    map.put("/user/add", "authc"); //必须认证了才能访问
    map.put("/user/update", "authc");
    //上面两个可以使用通配符  map.put("/user/*","authc");
    //授权,若当前登录用户未授权则会跳转到授权页面
    map.put("/user/add", "perms[user:add]");
    map.put("/user/update", "perms[user:update]");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
    //设置登录页面
    shiroFilterFactoryBean.setLoginUrl("/login");
    //设置未授权页面
    shiroFilterFactoryBean.setUnauthorizedUrl("/unauth");

    return shiroFilterFactoryBean;
}

上面代码中的unauth是在templates目录下编写的页面:

DOCTYPE html>

    
        
        未授权
    
    
        未经授权,不能访问!
    

第二步:在DispatchController中添加如下代码:
@RequestMapping("/unauth")
public String unauth(){
    return "unauth";
}
第三步:修改UserRealm中的doGetAuthorizationInfo方法,在其中添加获取当前用户权限的代码:
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
   System.out.println("============doGetAuthorizationInfo==============");
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

    Subject subject = SecurityUtils.getSubject();
    User user = (User) subject.getPrincipal();
    //模拟从数据库中查询出权限
    Set permissions = DB.getAuths(user.getId());

    simpleAuthorizationInfo.setStringPermissions(permissions);//添加权限

    return simpleAuthorizationInfo;
}

部署项目运行,发现随着登录用户的不同,所能进行的操作也随之不同。

Shiro整合Thymeleaf 第一步:增加Maven依赖

    com.github.theborakompanioni
    thymeleaf-extras-shiro
    2.0.0

第二步:修改配置类ShiroConfig,在其中添加Shiro整合thymeleaf的代码:
@Bean
public ShiroDialect getShiroDialect() {
    ShiroDialect shiroDialect = new ShiroDialect();
    return shiroDialect;
}
第三步:修改index.html页面
DOCTYPE html>

    
        
        首页
    
    
        
            登录
        
        
            退出登录
        
        
        
        
        
            增加用户
        
        
            修改用户
        
    

部署项目,打开首页只显示登录超连接文字,随着登录用户的不同,后续打开的页面显示不同的文字。

Shiro整合MyBatis 第一步:添加Maven依赖

    mysql
    mysql-connector-java


    com.baomidou
    mybatisplus-spring-boot-starter
    1.0.5


    com.baomidou
    mybatis-plus
    3.4.0

第二步:后台数据表结构:

在这里插入图片描述

第三步:采用MyBatisCodeHelperPro插件生成实体类、Mapper、Service代码 第四步:修改
public class UserRealm extends AuthorizingRealm {

    @Resource
    private UserAuthService userAuthService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
       System.out.println("===========doGetAuthorizationInfo===============");
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        //模拟从数据库中查询出权限

        Set permissions = new HashSet();
        List auths = userAuthService.getAuthsByUserId(user.getId());
        for(Auth auth : auths){
            permissions.add(auth.getCode());
        }

        simpleAuthorizationInfo.setStringPermissions(permissions);//添加权限
        return simpleAuthorizationInfo;
    }

    @Resource
    private UserService userService;
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException{
        System.out.println("====doGetAuthenticationInfo==========");
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;

        //从数据库中获取用户信息
        User user = userService.getUserByUsername(userToken.getUsername());
        if (null == user) { //用户不存在
            return null; //抛出异常UnknownAccountException
        }
        //用户登录成功,将用户信息保存在Shiro的session中
        SecurityUtils.getSubject().getSession()
                .setAttribute("currentLoginedUser",user);
        //不能(不建议)自己做密码认证,系统会自己做
        // 第一个参数为完整用户信息,方便授权时查找用户的权限
        return new SimpleAuthenticationInfo(user, user.getUserpwd(), "");
    }

} 
关注
打赏
1688896170
查看更多评论

梁云亮

暂无认证

  • 5浏览

    0关注

    1176博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0531s