002-shiro的HelloWorld入门

本文介绍了如何使用Maven创建一个Apache Shiro项目,详细讲解了Shiro的核心jar包导入、shiro.ini配置文件的编写,包括用户、角色和权限的定义。此外,还展示了登录异常处理和基本的示例代码,演示了Shiro的认证流程。通过此教程,读者可以了解Shiro的基础功能和权限控制机制。
摘要由CSDN通过智能技术生成

目录

前提

1.使用maven创建一个shiro1项目

2.导入shiro核心jar包

shiro.ini文件

[users]格式说明

[roles]格式说明

[main]说明

3.编写示例代码

4.登录异常的处理

总结


前提

学习本课程内容,请确保你已经具有如下内容的使用经验:

  • maven
  • idea
  • spring、springboot等

1.使用maven创建一个shiro1项目

2.导入shiro核心jar包

本教程使用maven导入

    <dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.7.1</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.30</version>
        </dependency>

    </dependencies>

1.7.1为文章编写时的最新版本,大家可以选择适合自己的版本

slf4j依赖是shiro的依赖,不依赖也不会报错,建议依赖

shiro.ini文件

src/main/resources目录下创建一个shiro.ini文件内容如下:


[users]
admin = password,admin
user1 = password, role1, role2
user2 = password, role1
user3 = password


[roles]
# 'admin' 角色包含所有权限, 权限的值设定为 '*'
admin = *
# 角色1包含"p1:"开头的所有权限
role1 = p1:*
# 角色2拥有两个权限p1:o1:c1,p2:o2:c2
role2 = p1:o1:c1,p2:o2:c2

[users]格式说明

usernamepasswordroleName1roleName2,...,roleNameN

  • 等号左侧的值是用户名
  • 等号右边的第一个值是用户的密码。必须输入密码。
  • 密码后的任何逗号分隔值都是分配给该用户的角色的名称。角色名称是可选的。
  • 密码还可以加密,这个我们后面再讨论。(可通过myRealm.setCredentialsMatcher(sha256Matcher))CredentialsMatcher就是我们的密码加密策略。

[roles]格式说明

rolename=权限定义1权限定义2,...,权限定义N

其中每个权限定义是一个任意字符串,但大多数人将要使用符号串,当然这些权限不要重名了。shiro还支持带*号的复杂格式的权限(更详细的权限规则请参考官网http://shiro.apache.org/permissions.html

[main]说明

本例暂时没有使用,其主要用于定义SecurityManager实例及其任何依赖项,例如Realm。

[main]
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher

myRealm = com.company.security.shiro.DatabaseRealm
myRealm.connectionTimeout = 30000
myRealm.username = jsmith
myRealm.password = secret
myRealm.credentialsMatcher = $sha256Matcher

securityManager.sessionManager.globalSessionTimeout = 1800000

使用[main]需要使用如下代码启用shiro

Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);

IniSecurityManagerFactory会自动装配[main]中定义的各种属性类似于spring的依赖注入,由于我们实际开发中shiro常常是和spring一起使用的,所以ini方式是比较少用的。在1.7.1版本中IniSecurityManagerFactory已经被@Deprecated不建议使用了。

3.编写示例代码

package com.yyoo.mytest.shiro1.demo;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;


public class Demo1 {

    public static void main(String[] args) {

        //1.定义领域
        Realm realm = new IniRealm("classpath:shiro.ini");

        //2.定义shiro的核心SecurityManager,注意import,java.lang包也有个SecurityManager,但不是我们需要的
        SecurityManager securityManager = new DefaultSecurityManager(realm);

        //3.为全局对象SecurityUtils设置securityManager
        SecurityUtils.setSecurityManager(securityManager);
        // 以上为shiro的初始化(启用)代码


        // 以下为shiro的登录认证等代码
        Subject subject = SecurityUtils.getSubject();
        System.out.println("登录前:");
        print(subject);

        // 此处更换其他用户名密码试试
        UsernamePasswordToken token = new UsernamePasswordToken("admin","password");
        subject.login(token);

        System.out.println("\n\n登录后:");
        print(subject);

        // 退出
        subject.logout();
        System.out.println("\n\n退出后:");
        print(subject);

    }


    public static void print(Subject subject){
        System.out.println("是否认证:" + subject.isAuthenticated());
        System.out.println("是否是记住登录的:" + subject.isRemembered());
        System.out.println("是否是角色role1:" + subject.hasRole("role1"));
        System.out.println("是否具有权限p1:" + subject.isPermitted("p1"));
        System.out.println("是否具有权限p1:o1:c1:" + subject.isPermitted("p1:o1:c1"));
        System.out.println("是否具有权限p2:o2:c2:" + subject.isPermitted("p2:o2:c2"));
    }

}

大家自行把用户admin、user1、user2、user3和其他没有定义的用户带入方法执行看看结果,认真分析结果,对你理解shiro的权限控制会有帮助。

4.登录异常的处理

当我们带入其他没有定义的用户执行时,会出现如下异常:

Exception in thread "main" org.apache.shiro.authc.UnknownAccountException: Realm [org.apache.shiro.realm.text.IniRealm@66cd51c3] was unable to find account data for the submitted AuthenticationToken [org.apache.shiro.authc.UsernamePasswordToken - user33, rememberMe=false].
	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:184)
	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:273)
	at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
	at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
	at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275)
	at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)

UnknownAccountException通过异常名就能知道,这是用户名不存在的异常,但我们在实际使用中最好不要提示“用户名不存在”,避免被人暴力破解账号。我们示例中也没有对这些异常进行处理规避,所以我们的示例代码还得优化,将

subject.login(token);

这行代码优化如下:

try {
	subject.login(token);
} catch (UnknownAccountException e) {// 用户不存在
	logger.error("用户名或密码错误",e);
	throw new RuntimeException("用户名密码错误");
} catch (LockedAccountException e) {
	logger.error("账户被锁定",e);
	throw new RuntimeException("账户被锁定");
} catch (IncorrectCredentialsException e) {// 密码错误
	logger.error("用户名或密码错误",e);
	throw new RuntimeException("用户名密码错误");
}catch (AuthenticationException e){
	logger.error("用户名密码错误",e);
	throw new RuntimeException("用户名密码错误");
}

总结

我们的HelloWorld虽然并不复杂,也不够全面,但shiro的基本功能都得以体现,特别用户、角色、权限以及权限的简单规则我们都有了初步的认识,能清楚认识到这几个点,对我们后续架构中设计项目的权限功能会有很大帮助。

上一篇:001-shiro简介

下一篇:003-认证

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值