本文共 8513 字,大约阅读时间需要 28 分钟。
shiro是一个Apache的开源安全框架,提供认证,授权,企业会话管理,安全加密,缓存管理等
最上面部分 操作用户
操作核心(Security Manager)
1、authenticator : 认证器(登录登出)
2、authorizer : 授权器(赋予主体有哪些权限)
3、session manager :session管理器(可以在不使用任何框架的情况下管理session)
4、cache manager : 缓存管理器 (管理操作缓存数据)
5、session dao : 提供session操作(增删改查)
6、realms : shiro和桥梁 认证信息权限数据角色数据都是通过它来获取
最右边是shiro的加密工具
底部数据库部分
认证流程图
1、使用SimpleAccountRealm实现认证授权过程pom
org.apache.shiro shiro-core 1.4.0 junit junit RELEASE AuthenticatorTestimport 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
IniRealmTestimport 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
JDBCRealmTestimport 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 { MapuserMap = 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/