全注解 springboot 集成 shiro 盐值加密

记录一下自己集成shiro的步骤,也是第一次使用,很多地方比较生硬

1.导入pom包

 		<!-- shiro -->

        <dependency>

            <groupId>org.apache.shiro</groupId>

            <artifactId>shiro-spring</artifactId>

            <version>1.3.2</version>

        </dependency>

2.配置shiro

@Configuration
public class ShiroConfiguration {

    //将自己的验证方式加入容器
    @Bean
    public MyShiroRealm myShiroRealm() {
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        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();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> filterChainDefinitionMap = new HashMap<String, String>();
        //对所有用户认证
        filterChainDefinitionMap.put("/plat/**","authc");
        filterChainDefinitionMap.put("/index/**","authc");
        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //错误页面,认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/login");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    //设置默认加密方式
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        // 使用md5 算法进行加密
        hashedCredentialsMatcher.setHashAlgorithmName(ShiroVerityUtil.ALGORITHM_NAME);
        // 设置散列次数: 意为加密几次
        hashedCredentialsMatcher.setHashIterations(ShiroVerityUtil.HASH_ITERATIONS);
        return hashedCredentialsMatcher;
    }

    //加入注解的使用,不加入这个注解不生效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

3.编写实现realm

//实现AuthorizingRealm接口用户用户认证
public class MyShiroRealm extends AuthorizingRealm {

    //用于用户查询
    @Autowired
    private IAdminService iAdminService;

    //角色权限和对应权限添加
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String username = (String) principalCollection.getPrimaryPrincipal();
        //查询用户名称
        QueryWrapper<Admin> adminQueryWrapper = new QueryWrapper<>();
        adminQueryWrapper.lambda().eq(Admin::getLoginName, username);
        Admin admin = iAdminService.getOne(adminQueryWrapper);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Role role : admin.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getName());
            for (Permission permission : role.getPermissions()) {
                //添加权限
                simpleAuthorizationInfo.addStringPermission(permission.getName());
            }
        }
        return simpleAuthorizationInfo;
    }

    //用户认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        Subject subject = SecurityUtils.getSubject();
        Session httpSession = subject.getSession();
        //加这一步的目的是在Post请求的时候会先进认证,然后在到请求
        if (authenticationToken.getPrincipal() == null) {
            return null;
        }
        //获取用户信息
        String username = authenticationToken.getPrincipal().toString();
        //查询用户名称
        QueryWrapper<Admin> adminQueryWrapper = new QueryWrapper<>();
        adminQueryWrapper.lambda().eq(Admin::getLoginName, username);
        Admin admin = iAdminService.getOne(adminQueryWrapper);
        if (admin == null) {
            //这里返回后会报出对应异常
            throw new UnknownAccountException();
        } else {
            String password = admin.getPassword();
            ByteSource salt = ByteSource.Util.bytes(admin.getLoginName() + admin.getSalt());
            String realmName = getName();
            try{
                //这里验证authenticationToken和simpleAuthenticationInfo的信息
                SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( username, password, salt,  realmName );
                //验证通过后,注入对象
                List<Permission> permissions = iAdminService.getAdminMenus(admin.getId());
                httpSession.setAttribute("admin",admin);
                httpSession.setAttribute("menus",permissions);
                httpSession.setTimeout(ShiroVerityUtil.SESSION_TIME_OUT);
                ShiroVerityUtil.setCunrrentAdmin(admin);
                return simpleAuthenticationInfo;
            }catch (Throwable t){
                throw new AuthenticationException();
            }

        }
    }
}

4.加密类

public class ShiroVerityUtil {

    public static String SALT_STR = "salt";
    public static String PASSWORD_STR = "password";
    public static String LOGIN_NAME_STR = "loginName";
    //加密方式
    public static String ALGORITHM_NAME = "md5";
    //加密次数
    public static int HASH_ITERATIONS = 2;
    //session过期时间 ms
    public static int SESSION_TIME_OUT = 5 * 60 * 1000;

    private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();

    /**
     * shiro 盐值加密
     */
    public static void encryptPassword(Map userFormMap) {
        String salt = MapUtils.getString(userFormMap, SALT_STR);
        if (StringUtils.isBlank(salt)) {
            salt = randomNumberGenerator.nextBytes().toHex();
            userFormMap.put(SALT_STR, salt);
        }
        String newPassword = new SimpleHash(
                ALGORITHM_NAME,
                userFormMap.get(PASSWORD_STR),
                ByteSource.Util.bytes(userFormMap.get(LOGIN_NAME_STR) + salt),
                HASH_ITERATIONS
        ).toHex();
        userFormMap.put(PASSWORD_STR, newPassword);
    }

    /**
     * @return
     * @Title: getCunrrentAdminSyBranch
     * @Description: 获得登录人的分部
     * @author: zhenglei
     * @date: 2018年9月7日 上午10:00:17
     */
    public static JsonResult getCunrrentAdminSyBranch() {
        JsonResult b = new JsonResult();
        Admin cunrrentAdmin = ShiroVerityUtil.getCunrrentAdmin();
        if (cunrrentAdmin == null) {
            b.setFailInfo500();
            b.setMessage(CommonText.NOT_LOGIN);
            return b;
        }
        String syBranch = cunrrentAdmin.getSyBranch();
        if (StringUtils.isBlank(syBranch)) {
            b.setFailInfo500();
            b.setMessage(CommonText.NOT_LOGIN);
            return b;
        }
        b.setData(syBranch);
        return b;
    }

    /**
     * @return
     * @Title: getCunrrentAdmin
     * @Description: 获得当前登录人
     * @author: zhenglei
     * @date: 2018年9月5日 下午2:33:47
     */
    public static Admin getCunrrentAdmin() {
        Subject subject = SecurityUtils.getSubject();
        Session httpSession = subject.getSession();
        Object attribute = httpSession.getAttribute(SystemConstant.ADMIN_SESSION);
        if (attribute == null) {
            return null;
        }
        return (Admin) attribute;
    }

    /**
     * @return
     * @Title: setCunrrentAdmin
     * @Description: 获设置当前登录人
     * @author: zhenglei
     * @date: 2018年9月5日 下午2:33:47
     */
    public static void setCunrrentAdmin(Admin admin) {
        Subject subject = SecurityUtils.getSubject();
        Session httpSession = subject.getSession();
        httpSession.setAttribute(SystemConstant.ADMIN_SESSION, admin);
    }
}

5.登录loginController编辑

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

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

    @GetMapping("logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "/login";
    }

   @PostMapping("/postLogin")
    public String postLogin(String username, String password){
       //添加用户认证信息
       Subject subject = SecurityUtils.getSubject();
       Session session = subject.getSession();
       UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);
       try {
           // 执行登陆
           subject.login(usernamePasswordToken);
           subject.isPermitted();
       } catch ( UnknownAccountException e ) {
           session.setAttribute(CommonText.LOGIN_ERR_MSG,CommonText.ACCOUNT_DOES_NOT_EXIST);
           return "redirect:/login";
       } catch ( IncorrectCredentialsException e ) {
           session.setAttribute(CommonText.LOGIN_ERR_MSG,CommonText.PASSWORD_DOES_NOT_CORRECT);
           return "redirect:/login";
       } catch ( LockedAccountException e ) {
           session.setAttribute(CommonText.LOGIN_ERR_MSG,CommonText.ADMIN_DOES_NOT_EXIST);
           return "redirect:/login";
       } catch ( ExcessiveAttemptsException e ) {
           session.setAttribute(CommonText.LOGIN_ERR_MSG,CommonText.MORT_TIME_TRY);
           return "redirect:/login";
       }
       return "redirect:/index";
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值