Shiro安全框架入门笔记(一)

纵然是瞬间 提交于 2020-01-10 11:25:51

一、Shiro简介

shiro是一个Apache的开源安全框架,提供认证,授权,企业会话管理,安全加密,缓存管理等

 

二、Shiro整体架构

最上面部分  操作用户 

操作核心(Security Manager)

1、authenticator : 认证器(登录登出)

2、authorizer : 授权器(赋予主体有哪些权限)

3、session manager :session管理器(可以在不使用任何框架的情况下管理session)

4、cache manager : 缓存管理器 (管理操作缓存数据)

5、session dao : 提供session操作(增删改查)

6、realms : shiro和桥梁 认证信息权限数据角色数据都是通过它来获取 

最右边是shiro的加密工具

底部数据库部分

 

三、Shiro认证 、授权、自定义realm

认证流程图



1、使用SimpleAccountRealm实现认证授权过程

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>
AuthenticatorTest
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 AuthenticatorTest {

    SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();

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

    @Test
    public void TestAuthenticator(){

        //1.构建 securitymanager环境
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        defaultSecurityManager.setRealm(simpleAccountRealm);

        //2.主体提交认证请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

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

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

账号错误,会抛出Realm不能识别的账号异常

密码错误,会抛出不正确的认证异常

另外,shiro还提供了登出功能

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

2、使用iniRealm实现认证授权过程

ini文件内容

[users]
Mark=1234,admin
[roles]
admin=user:delete
IniRealmTest
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;

import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;

import org.junit.Test;

public class IniRealmTest {

    IniRealm iniRealm = new IniRealm("classpath:user.ini");

    @Test
    public void TestIniRealm(){

        //1.构建 securitymanager环境
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        defaultSecurityManager.setRealm(iniRealm);

        //2.主体提交认证请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

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

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

        subject.checkRole("admin");
        subject.checkPermission("user:delete");
        /*subject.logout();
        System.out.println("isAuthenticated: "+subject.isAuthenticated());*/
    }
}

3、使用JDBCRealm实现认证授权过程

自定义表结构

user

role

permissions

JDBCRealmTest
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;

public class JDBCRealmTest {

    DruidDataSource dataSource = new DruidDataSource();
    {
        dataSource.setUrl("jdbc:mysql://localhost:3306/jdbcrealm");
        dataSource.setUsername("root");
        dataSource.setPassword("1234");
    }


    @Test
    public void TestJDBCRealm(){

        JdbcRealm JdbcRealm = new JdbcRealm();
        JdbcRealm.setDataSource(dataSource);

        JdbcRealm.setPermissionsLookupEnabled(true);

        //自定义sql语句
        String sql = "select password from user where user_name = ?";
        JdbcRealm.setAuthenticationQuery(sql);

        String roleSql = "select role from role where user_name = ?";
        JdbcRealm.setUserRolesQuery(roleSql);

        String permissionSql = "select permissions from permissions where role = ?";
        JdbcRealm.setPermissionsQuery(permissionSql);

        //1.构建 securitymanager环境
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        defaultSecurityManager.setRealm(JdbcRealm);

        //2.主体提交认证请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken("xiaoming","1234");
        subject.login(token);

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

        subject.checkRole("user");
        subject.checkPermission("login");

    }
}

4、自定义realm

注:包含了加密和加盐

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class CustomRealm extends AuthorizingRealm {

    Map<String,String> userMap = new HashMap<String, String>(16);
    {
        //81dc9bdb52d04dc20036dbd8313ed055
        userMap.put("Mark","f2d9ffba24994ac1cbeff23d94ddb62a");
        super.setName("CustomRealm");
        //Thread.currentThread().setName();为当前线程设置名称
    }

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String username = (String) principals.getPrimaryPrincipal();
        //模拟从数据库或缓存中获取角色数据
        Set<String> roles = getRolesByUsername(username);
        Set<String> permissions = getPermissionsByUsername(username);

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);
        info.setStringPermissions(permissions);

        return info;
    }

    private Set<String> getPermissionsByUsername(String username) {

        Set<String> set = new HashSet<String>();
        set.add("user:delete");
        set.add("user:update");
        return set;
    }

    private Set<String> getRolesByUsername(String username) {

        Set<String> set = new HashSet<String>();
        set.add("admin");
        set.add("user");
        return set;
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //1、AuthenticationToken 主体传过来的认证信息中,获取用户名
        String username = (String)token.getPrincipal();
        //2、通过用户名到数据库中获取凭证
        String password =  getPasswordByUsername(username);

        if(password==null){
            return null;
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo("Mark",password,"CustomRealm");
        info.setCredentialsSalt(ByteSource.Util.bytes("Mark"));

        return info;
    }

    //模拟数据库查询凭证
    private String getPasswordByUsername(String username) {
        return userMap.get(username);
    }

    public static void main(String[] args) {
        Md5Hash md5Hash = new Md5Hash("1234","Mark");
        System.out.println(md5Hash.toString());
    }
}

 测试

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
import realm.CustomRealm;

public class CustomRealmTest {

    CustomRealm customRealm = new CustomRealm();

    @Test
    public void TestIniRealm(){

        //1.构建 securitymanager环境
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        defaultSecurityManager.setRealm(customRealm);

        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("MD5");
        matcher.setHashIterations(1);

        customRealm.setCredentialsMatcher(matcher);
        //2.主体提交认证请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

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

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

        subject.checkRole("admin");
        subject.checkPermission("user:delete");

    }
}

 

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!