Shiro简单入门-Springboot

学习视频:【狂神说Java】SpringBoot整合Shiro框架
真正的大师永远保持着一颗学徒的心

目录

Shiro简介

官网:https://shiro.apache.org/

Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications

ApacheShiro™是一个功能强大且易于使用的JAVA安全框架,用于执行身份验证、授权、加密和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地保护任何应用程序–从最小的移动应用程序到最大的Web和企业应用程序

Shiro架构图

学习

说明:
狂神的视频是没有前后端分离,用的是Thymeleaf,我用的是前后端分离,理论上传递的都是json字符串,所有
看视频可能有点懵

快速开始

public class Quickstart {

    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);

    public static void main(String[] args) {

        //初始化Ini的Realm
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();

        //设置安全工具的管理器
        SecurityUtils.setSecurityManager(securityManager);
        //获取Subject
        Subject currentUser = SecurityUtils.getSubject();
        //获取Session
        Session session = currentUser.getSession();
        //设置相关参数
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("Retrieved the correct value! [" + value + "]");
        }
        //判断当前用户是否认证
        if (!currentUser.isAuthenticated()) {
            //新建认证令牌
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            //设置记住我
            token.setRememberMe(true);
            try {
                //登录
                currentUser.login(token);
            } catch (UnknownAccountException uae) {
                //用户名不存在
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                //密码错误
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                //用户被锁定
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            //总异常:认证异常
            catch (AuthenticationException ae) {
            }
        }
        //currentUser.getPrincipal() -> 获取用户一些信息
        log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
        //判断是否拥有角色
        if (currentUser.hasRole("schwartz")) {
            log.info("May the Schwartz be with you!");
        } else {
            log.info("Hello, mere mortal.");
        }
        //判断是否拥有权限 -> 简单权限
        if (currentUser.isPermitted("lightsaber:wield")) {
            log.info("You may use a lightsaber ring.  Use it wisely.");
        } else {
            log.info("Sorry, lightsaber rings are for schwartz masters only.");
        }
        //判断是否拥有权限 -> 高级的权限
        if (currentUser.isPermitted("winnebago:drive:eagle5")) {
            log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                    "Here are the keys - have fun!");
        } else {
            log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
        }
        //退出
        currentUser.logout();

        System.exit(0);
    }
}

整合Springboot(基础)

导入jar包

<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring-boot-web-starter -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.5.3</version>
</dependency>

编写自定义Realm

public class RolesRealm extends AuthorizingRealm {

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

	@Override
	//认证
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		return null;
	}

}

编写配置文件

@Configuration
public class ShiroConfig {
	
    public RolesRealm realm() {
        RolesRealm realm = new RolesRealm();
        return realm;
    }
    
    public DefaultWebSecurityManager securityManager() {
    	DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    	securityManager.setRealm(realm());
    	return securityManager;
    }
    
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
    	ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    	shiroFilterFactoryBean.setSecurityManager(securityManager());
    	
    	//map
    	Map<String, String> map = new LinkedHashMap<>();
    	map.put("/", "anon");
    	map.put("/user/add", "authc");

    	//添加shiro内置的过滤器
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

    	return shiroFilterFactoryBean;
    }
    
}

自定义未登录返回状态:(正常情况会重定向到一个页面,如果是前后端分离,我们希望返回json字符串)
shiro自定义未登录返回状态

认证

RolesRealm

public class RolesRealm extends AuthorizingRealm {

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

	@Override
	//认证
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = "admin";
		String password = "admin";
		//只需要验证用户名
		UsernamePasswordToken selfToken = (UsernamePasswordToken)token;
		if (!username.equals(selfToken.getUsername())) {
			return null;
		}
		//只需要返回的时候返回正确的密码,shiro内部就可以自动验证密码
		return new SimpleAuthenticationInfo(username, password, "");
	}

}

登录逻辑

@GetMapping("login")
public String login(
		@RequestParam(value = "username", required = true)String username, 
		@RequestParam(value = "password", required = true)String password) {
	Subject subject = SecurityUtils.getSubject();
	UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
	try {
		subject.login(usernamePasswordToken);
		return "success";
	} catch (AuthenticationException e) {
		// TODO: handle exception
		return "username or password error";
	}
	
}

授权

配置增加授权

map.put("/user/delete", "perms[user:delete]");放在上面

修改realm

@Override
//授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
	SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
	System.err.println("进行认证");
	info.addStringPermission("user:delete");
	return info;
}

最后

注意:在设置拦截器的时候

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
	ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
	shiroFilterFactoryBean.setSecurityManager(securityManager());
	
	//map
	Map<String, String> map = new LinkedHashMap<>();
	map.put("/", "anon");
	map.put("/user/delete", "perms[user:delete]");
	map.put("/user/*", "authc");

	//添加shiro内置的过滤器
    shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
    
    //用户未登录不进行跳转,而是自定义返回json数据
    Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();//获取filters
    filters.put("authc", new ShiroLoginFilter());//将自定义 的FormAuthenticationFilter注入shiroFilter中
	filters.put("perms", new ShiroPermsFilter());
	return shiroFilterFactoryBean;
}

拦截器的顺序有意义的如果map.put("/user/*", "authc");放在map.put("/user/delete","perms[user:delete]");上面,则不会执行授权验证,只会执行登录验证,原因未知

总结

这个博客只是Shiro入门,只是会略微使用Shiro,如果想继续学习,推荐尚硅谷教程:尚硅谷Shiro安全权限框架实战教程全套完整版(从入门到精通)

下篇文章:Shiro正式学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值