Shiro的授权与认证(简单入门)

一.Shiro的认证逻辑

在这里插入图片描述

代码演示

  1. 先在pom中配置依赖
<dependencies>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.0</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>RELEASE</version>
    </dependency>
</dependencies>

  1. 新建测试类AuthenticationTest
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;

public class AuthenticationTest {

    SimpleAccountRealm simpleAccountRealm=new SimpleAccountRealm();

    @Before
    public void addUser(){
        simpleAccountRealm.addAccount("Mark","123456");
    }

    @Test
    public void testAuthentication(){
        //1.构建SecurityManager环境
        DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
        defaultSecurityManager.setRealm(simpleAccountRealm);
        //2.主体认证提交请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token=new UsernamePasswordToken("Mark","123456");
        subject.login(token);

        System.out.println("isAuthenticated:"+subject.isAuthenticated());
        subject.logout();
        System.out.println("isAuthenticated:"+subject.isAuthenticated());
    }
}

  1. 测试结果
    在这里插入图片描述
  2. 从代码中分析认证逻辑
    在这里插入图片描述

二.Shiro的授权逻辑

在这里插入图片描述

代码演示

  1. 在认证的代码上修改
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;

public class AuthenticationTest {

    SimpleAccountRealm simpleAccountRealm=new SimpleAccountRealm();

    @Before
    public void addUser(){
        //添加用户名,密码,用户角色
        simpleAccountRealm.addAccount("Mark","123456","admin");
    }

    @Test
    public void testAuthentication(){
        //1.构建SecurityManager环境
        DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
        defaultSecurityManager.setRealm(simpleAccountRealm);
        //2.主体认证提交请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token=new UsernamePasswordToken("Mark","123456");
        subject.login(token);

        System.out.println("isAuthenticated:"+subject.isAuthenticated());

        //检查是否是管理员角色
        subject.checkRole("admin");

    }
}

  1. 从代码中分析授权逻辑

在这里插入图片描述

三.自定义Realm

1.创建自定义的CustomRealm
在这里插入图片描述
CustomRealm继承AuthorizingRealm类,该类有doGetAuthorizationInfo()、doGetAuthenticationInfo()方法。doGetAuthorizationInfo()用来编写授权逻辑,doGetAuthenticationInfo()方法用来编写认证逻辑。

public class CustomRealm extends AuthorizingRealm {
//授权逻辑
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    return null;
}
//认证逻辑
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
return null;
}
}

2.编写认证逻辑,因为是简单的测试,所以没有连接数据库,数据库用Map来模拟

public class CustomRealm extends AuthorizingRealm {

    /**
     * 模拟数据库中的数据
     */
    Map<String,String> userMap=new HashMap<>(16);
    {
        userMap.put("Mark","123456");
        super.setName("customRealm");
    }
    //授权逻辑
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }


    //认证逻辑
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1.从主体传过来的认证信息中,获得用户名
        String userName =(String)authenticationToken.getPrincipal();
        //2.通过用户名到数据库中获取凭证
        String password=getPasswordByUserName(userName);
        if(password==null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo
                ("Mark",password,"customRealm");
        return authenticationInfo;
    }

    /**
     * 模拟数据库查询凭证
     * @param userName
     * @return
     */
    private String getPasswordByUserName(String userName) {
        return  userMap.get(userName);
    }
}

3.编写测试类CustomRealmTest
在这里插入图片描述

public class CustomRealmTest {

    @Test
    public void testAuthentication(){

        CustomRealm customRealm=new CustomRealm();

        //1.构建SecurityManager环境
        DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
        defaultSecurityManager.setRealm(customRealm);
        //2.主体认证提交请求,主体授权
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token=new UsernamePasswordToken("Mark","123456");
        subject.login(token);
        System.out.println("isAuthenticated:"+subject.isAuthenticated());

    }
}

4.测试结果
在这里插入图片描述
5.编写授权逻辑

//授权逻辑
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    String userName=(String)principalCollection.getPrimaryPrincipal();
    //从数据库或者缓存中获取角色数据
    Set<String> roles=getRolesByUserName(userName);
    Set<String> permissions=getPermissionsByUserName(userName);
    SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
    simpleAuthorizationInfo.setStringPermissions(permissions);
    simpleAuthorizationInfo.setRoles(roles);
    return simpleAuthorizationInfo;
}

/**
 * 模拟数据库查询角色权限
 * @param userName
 * @return
 */
private Set<String> getPermissionsByUserName(String userName) {
    Set<String> sets=new HashSet<>();
    sets.add("user:delete");
    sets.add("user:add");
    return sets;
}

/**
 * 模拟数据库查询角色
 * @param userName
 * @return
 */
private Set<String> getRolesByUserName(String userName) {
    Set<String> sets=new HashSet<>();
    sets.add("admin");
    sets.add("user");
    return sets;
}

6.测试

@Test
public void testAuthentication(){

    CustomRealm customRealm=new CustomRealm();

    //1.构建SecurityManager环境
    DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
    defaultSecurityManager.setRealm(customRealm);
    //2.主体认证提交请求,主体授权
    SecurityUtils.setSecurityManager(defaultSecurityManager);
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken token=new UsernamePasswordToken("Mark","123456");
    subject.login(token);
    System.out.println("isAuthenticated:"+subject.isAuthenticated());
    subject.checkRole("admin");
    subject.checkPermissions("user:add","user:delete");
    System.out.println("没有报错,说明正确");

}

结果
在这里插入图片描述
把user:add改为user:update,结果为
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值