ava1749144759
ava1749144759
2019-04-26 19:51

springboot下 shiro + redis 验证后无动作

  • spring
  • java
  • maven
  • intellij-idea

shiro + redis

由于shiro之前没有用过 , 这次使用也是比较仓促 希望大佬们多多帮组

                      跪谢

可以在redis中看到 session的存储

验证后并不跳转到首页

附上 代码

  1. 目录结构

图片说明

  1. shiroConfig.java

import com.chenzs.common.mapper.RoleMapper;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * @author ChenZS
 */
@Configuration
public class ShiroConfig {

    @Resource
    private RoleMapper roleMapper;

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        System.err.println("ShiroConfiguration.shirFilter() ---> start ");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器.
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断
//        filterChainDefinitionMap.put("/css/**", "authc");
//        filterChainDefinitionMap.put("/js/**", "authc");
//        filterChainDefinitionMap.put("/img/**", "authc");
//        filterChainDefinitionMap.put("/components/**", "authc");
//        filterChainDefinitionMap.put("/favicon.ico", "authc");
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
//        filterChainDefinitionMap.put("/logout", "logout");
        //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
//        filterChainDefinitionMap.put("/**", "authc");
        // 如果不设置默认会自动寻找Web工程根目录下的"/login"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
//        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/blog");
        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/404");

        filterChainDefinitionMap.put("/static/**", "anon");

//        filterChainDefinitionMap.put("/", "perms[admin]");
//        filterChainDefinitionMap.put("/user/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);



//        //从数据库获取  对应角色
//        List<Role> list = roleMapper.selectByExample(null);
//
//        for (SysPermissionInit sysPermissionInit : list) {
//            filterChainDefinitionMap.put(sysPermissionInit.getUrl(),
//                    sysPermissionInit.getPermissionInit());
//        }
//
//        shiroFilterFactoryBean
//                .setFilterChainDefinitionMap(filterChainDefinitionMap);
        System.out.println("Shiro拦截器工厂类注入成功");
        return shiroFilterFactoryBean;
    }
    /**
     * 凭证匹配器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
     * )
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        //散列的次数,比如散列两次,相当于 md5(md5(""));
        hashedCredentialsMatcher.setHashIterations(1);
        return hashedCredentialsMatcher;
    }
    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return myShiroRealm;
    }
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        //设置realm
        securityManager.setRealm(myShiroRealm());
        // 自定义缓存实现 使用redis
        securityManager.setCacheManager(cacheManager());
        // 自定义session管理 使用redis
        securityManager.setSessionManager(sessionManager());

        return securityManager;
    }
    /**
     *  开启shiro aop注解支持.
     *  使用代理方式;所以需要开启代码支持;
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    /**
     * cacheManager 缓存 redis实现
     * 使用的是shiro-redis开源插件
     *
     * @return
     */
    public RedisCacheManager cacheManager() {
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
        return redisCacheManager;
    }

    /**
     * 配置shiro redisManager
     * 使用的是shiro-redis开源插件
     *
     * @return
     */
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();
        redisManager.setHost("192.168.0.12");
        redisManager.setPort(6379);
        redisManager.setExpire(1800 * 60 *30);// 配置缓存过期时间
        redisManager.setTimeout(0);
        redisManager.setPassword("123456789+");
        // redisManager.setPassword(password);
        return redisManager;
    }

    /**
     * Session Manager
     * 使用的是shiro-redis开源插件
     */
    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionDAO(redisSessionDAO());
        return sessionManager;
    }

//    @Bean("sessionManager")
//    public SessionManager sessionManager(ShiroSessionDao shiroSessionDa){
//        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//        sessionManager.setGlobalSessionTimeout(60 * 60 * 1000);
//        sessionManager.setSessionValidationSchedulerEnabled(true);
//        sessionManager.setSessionIdUrlRewritingEnabled(false);
//        sessionManager.setSessionDAO(shiroSessionDao);
//        /** 此注释代码 就是将JSESSIONID变成自定义名称 WEBJSESSIONID
//         sessionManager.setSessionIdCookieEnabled(true);
//         SimpleCookie cookie = new SimpleCookie("WEBJSESSIONID");
//         cookie.setHttpOnly(true);
//         cookie.setMaxAge(60 * 60 * 1000);
//         sessionManager.setSessionIdCookie(cookie);  **/
//        return sessionManager;
//    }


    /**
     * RedisSessionDAO shiro sessionDao层的实现 通过redis
     * 使用的是shiro-redis开源插件
     */
    @Bean
    public RedisSessionDAO redisSessionDAO() {
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());
//
//        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//        sessionManager.setGlobalSessionTimeout(60 * 60 * 1000);
//        sessionManager.setSessionValidationSchedulerEnabled(true);
//        sessionManager.setSessionIdUrlRewritingEnabled(false);
//        /** 此注释代码 就是将JSESSIONID变成自定义名称 WEBJSESSIONID */
//         sessionManager.setSessionIdCookieEnabled(true);
//         SimpleCookie cookie = new SimpleCookie("WEBJSESSIONID");
//         cookie.setHttpOnly(true);
//         cookie.setMaxAge(60 * 60 * 1000);
//         sessionManager.setSessionIdCookie(cookie);
        return redisSessionDAO;
    }

}


  1. MyShiroRealm.java
import com.chenzs.common.model.Role;
import com.chenzs.common.model.User;
import com.chenzs.common.service.RoleService;
import com.chenzs.common.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;

/**
 * @author ChenZS
 */
public class MyShiroRealm extends AuthorizingRealm{

    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//        User user = (User) principals.getPrimaryPrincipal();
//        List<Role> roleList = roleService.listRolesByUser(user);
        // TODO  后续应根据用户id 获取对应的权限,而不是现在的所有权限 ( 现在只有一种权限 --> admin )
        List<Role> roleList = roleService.getListRole();
        for (Role role : roleList) {
            authorizationInfo.addRole(role.getRole());
        }
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.err.println("MyShiroRealm.doGetAuthenticationInfo() -->  开始权限验证!");
        //获取用户的输入的账号.
        String username = (String) token.getPrincipal();
        System.out.println(token.getCredentials());
        //通过username从数据库中查找 User对象,如果找到,没找到.
        //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
        User user = userService.getUser(username);
        if (user.getId() == null) {
            return null;
        }
//        User user = response.getData();
        if (!user.getStatus()) {
            throw new LockedAccountException(username + "账号未激活或账号被封禁!");
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user,
                user.getPassword(),
                getName()
        );
        return authenticationInfo;
    }

}
  1. loginController .java
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/login")
public class LoginController {

    private static final String PATH = "login/";

    @RequestMapping("")
    public String index() {
        return PATH + "index";
    }

    /**
     * 登录提交
     * @param model
     * @return
     * @throws Exception
     */
    @PostMapping("/login_info")
    public String login(@RequestParam(required = true, value = "userName") String userName,@RequestParam(required = true, value = "password") String password,
                        Model model) throws Exception {
        //1、验证用户名和密码
        org.apache.shiro.subject.Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userName, password);
        String msg = "OK";
        try {
            subject.login(usernamePasswordToken);
//            return "myhome/index";
        } catch (UnknownAccountException e) {
            System.err.println("UnknownAccountException -- > 账号不存在:");
            msg = "账号不存在!";
        } catch (IncorrectCredentialsException e) {
            System.err.println("IncorrectCredentialsException -- > 密码不正确:");
            msg = "密码不正确!";
        } catch (LockedAccountException e) {
            System.err.println("LockedAccountException -- > 账号被锁定");
            msg = "账号被锁定!";
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        model.addAttribute("msg", msg);
//        return PATH + "index";   
        return "myhome/index";
    }

}

wechat: chen1749144759 求大佬 帮助 真的没有赏金了

  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

0条回答