博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Shiro安全框架入门笔记(一)
阅读量:3958 次
发布时间:2019-05-24

本文共 8513 字,大约阅读时间需要 28 分钟。

一、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

org.apache.shiro
shiro-core
1.4.0
junit
junit
RELEASE
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
userMap = new HashMap
(16); { //81dc9bdb52d04dc20036dbd8313ed055 userMap.put("Mark","f2d9ffba24994ac1cbeff23d94ddb62a"); super.setName("CustomRealm"); //Thread.currentThread().setName();为当前线程设置名称 } protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); //模拟从数据库或缓存中获取角色数据 Set
roles = getRolesByUsername(username); Set
permissions = getPermissionsByUsername(username); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setRoles(roles); info.setStringPermissions(permissions); return info; } private Set
getPermissionsByUsername(String username) { Set
set = new HashSet
(); set.add("user:delete"); set.add("user:update"); return set; } private Set
getRolesByUsername(String username) { Set
set = new HashSet
(); 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");    }}

 

 

 

 

转载地址:http://moazi.baihongyu.com/

你可能感兴趣的文章
代理模式、静态代理、动态代理、aop
查看>>
Struts1.x Spring2.x Hibernate3.x DWR2.x整合工具文档v1.00
查看>>
大型Web2.0站点构建技术初探
查看>>
机器学习算法汇总:人工神经网络、深度学习及其它
查看>>
解决Spring中AOP不能切入Struts的DispatchAction方法的问题
查看>>
出国以后才知道英语应该怎么学
查看>>
计算机专业权威期刊投稿经验总结
查看>>
如何在三个月内学会一门外语?
查看>>
看看你对Linux到底了解多少?
查看>>
网上看到的:ARM入门最好的文章(转)
查看>>
中国最美情诗100句
查看>>
javascript注册window的onload事件问题研究
查看>>
客户端技术分页控件javascript+css,可用于任何服务器端技术
查看>>
学习Swing 的网站[转]
查看>>
Google App engine 的第一个应用 midispot
查看>>
提问的智慧
查看>>
关于dom4j无法解析xmlns问题及生成非UTF-8字符集乱码问题的解决
查看>>
很好的一篇文章 如果让我重做一次研究生 王汎森
查看>>
保护U盘批处理文件
查看>>
hibernate 自动导入sql 文件import.sql 国际化编码的问题的解决方案
查看>>