电商网站建设讯息,教你做面食的网站,大连精美网站制作,什么是服务器文章目录 Shiro框架介绍Shiro 基本使用SimpleAccountRealmIniRealmJdbcRealmCustomRealm#xff08;自定义Realm#xff09; Shiro框架介绍
Apache Shiro是一个强大且易用的Java安全框架#xff0c;它执行身份验证、授权、密码和会话管理。Shiro框架通过其三个核心组件自定义Realm Shiro框架介绍
Apache Shiro是一个强大且易用的Java安全框架它执行身份验证、授权、密码和会话管理。Shiro框架通过其三个核心组件Subject、SecurityManager和Realms提供了一个通用的安全认证框架。
Shiro官方http://shiro.apache.org
Shiro的核心架构图 Shiro 基本使用
认证流程 授权流程 SimpleAccountRealm
认证代码
Test
public void authen() {//认证的发起者(subject) SecurityManager Realm//1. 准备Realm基于内存存储用户信息SimpleAccountRealm realm new SimpleAccountRealm();realm.addAccount(admin, admin, 超级管理员, 商家);//2. 准备SecurityManagerDefaultSecurityManager securityManager new DefaultSecurityManager();//3. SecurityManager和Realm建立连接securityManager.setRealm(realm);//4. subject和SecurityManager建立联系SecurityUtils.setSecurityManager(securityManager);//5. 声明subjectSubject subject SecurityUtils.getSubject();//6. 发起认证subject.login(new UsernamePasswordToken(admin, admin));// 如果认证时用户名错误抛出org.apache.shiro.authc.UnknownAccountException异常// 如果认证时密码错误抛出org.apache.shiro.authc.IncorrectCredentialsException://7. 判断是否认证成功System.out.println(subject.isAuthenticated());//8. 退出登录后再判断// subject.logout();// System.out.println(logout方法执行后认证的状态 subject.isAuthenticated());//9. 授权是在认证成功之后的操作// SimpleAccountRealm只支持角色的授权System.out.println(是否拥有超级管理员角色 subject.hasRole(超级管理员));subject.checkRole(商家);// check方法校验角色时如果没有指定角色会抛出异常org.apache.shiro.authz.UnauthorizedException: Subject does not have role [角色信息]
}IniRealm
基于文件存储用户名、密码、角色等信息
准备一个.ini文件存储用户信息并且IniRealm支持权限校验
[users]
usernamepassword,role1,role2
adminadmin,超级管理员,运营
[roles]
role1perm1,perm2
超级管理员user:add,user:update,user:delete代码
Test
public void authen(){//1. 构建IniRealmIniRealm realm new IniRealm(classpath:shiro.ini);//2. 构建SecurityManager绑定RealmDefaultSecurityManager securityManager new DefaultSecurityManager();securityManager.setRealm(realm);//3. 基于SecurityUtils绑定SecurityManager并声明subjectSecurityUtils.setSecurityManager(securityManager);Subject subject SecurityUtils.getSubject();//4. 认证操作subject.login(new UsernamePasswordToken(admin,admin));//5. 角色校验// 超级管理员System.out.println(subject.hasRole(超级管理员));subject.checkRole(运营);//6. 权限校验System.out.println(subject.isPermitted(user:update));// 如果没有响应的权限就抛出异常UnauthorizedException: Subject does not have permission [user:select]subject.checkPermission(user:delete);
}JdbcRealm
基于数据库存储用户名、密码、角色等信息。
用户认证、授权时推荐的表结构设计经典五张表 代码
Test
public void authen(){//1. 构建IniRealmJdbcRealm realm new JdbcRealm();DruidDataSource dataSource new DruidDataSource();dataSource.setDriverClassName(com.mysql.jdbc.Driver);dataSource.setUrl(jdbc:mysql:///shiro);dataSource.setUsername(root);dataSource.setPassword(root);realm.setDataSource(dataSource);realm.setPermissionsLookupEnabled(true);//2. 构建SecurityManager绑定RealmDefaultSecurityManager securityManager new DefaultSecurityManager();securityManager.setRealm(realm);//3. 基于SecurityUtils绑定SecurityManager并声明subjectSecurityUtils.setSecurityManager(securityManager);Subject subject SecurityUtils.getSubject();//4. 认证操作subject.login(new UsernamePasswordToken(admin,admin));//5. 授权操作(角色)System.out.println(subject.hasRole(超级管1理员));//6. 授权操作(权限)System.out.println(subject.isPermitted(user:add));}SQL构建代码
DROP TABLE IF EXISTS roles_permissions;
CREATE TABLE roles_permissions (id int(11) NOT NULL AUTO_INCREMENT,permission varchar(128) NOT NULL,role_name varchar(128) NOT NULL,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT4 DEFAULT CHARSETutf8mb4;-- ----------------------------
-- Records of roles_permissions
-- ----------------------------
INSERT INTO roles_permissions VALUES (1, user:add, 超级管理员);
INSERT INTO roles_permissions VALUES (2, user:update, 超级管理员);
INSERT INTO roles_permissions VALUES (3, user:select, 运营);-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS users;
CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT,username varchar(32) NOT NULL,password varchar(32) NOT NULL,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8mb4;-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO users VALUES (1, admin, admin);-- ----------------------------
-- Table structure for user_roles
-- ----------------------------
DROP TABLE IF EXISTS user_roles;
CREATE TABLE user_roles (id int(11) NOT NULL AUTO_INCREMENT,role_name varchar(128) NOT NULL,username varchar(32) NOT NULL,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8mb4;-- ----------------------------
-- Records of user_roles
-- ----------------------------
INSERT INTO user_roles VALUES (1, 超级管理员, admin);
INSERT INTO user_roles VALUES (2, 运营, admin);CustomRealm自定义Realm
仿照JdbcRealm实现一个自定义的Realm对象
声明POJO类继承AuthorizingRealm public class CustomRealm extends AuthorizingRealm {……………………}重写doGetAuthenticationInfo方法认证 /*** 认证方法只需要完成用户名校验即可密码校验由Shiro内部完成* param token 用户传入的用户名和密码* return* throws AuthenticationException*/Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//1. 基于Token获取用户名String username (String) token.getPrincipal();//2. 判断用户名非空if(StringUtils.isEmpty(username)){// 返回null会默认抛出一个异常org.apache.shiro.authc.UnknownAccountExceptionreturn null;}//3. 如果用户名不为null基于用户名查询用户信息User user this.findUserByUsername(username);//4. 判断user对象是否为nullif(user null){return null;}//5. 声明AuthenticationInfo对象并填充用户信息SimpleAuthenticationInfo info new SimpleAuthenticationInfo(user,user.getPassword(),CustomRealm!!);//6. 返回inforeturn info;}// 模拟数据库操作private User findUserByUsername(String username) {if(admin.equals(username)){User user new User();user.setId(1);user.setUsername(admin);user.setPassword(admin);return user;}return null;}重写doGetAuthenticationInfo方法密码加密加盐 {HashedCredentialsMatcher matcher new HashedCredentialsMatcher();matcher.setHashAlgorithmName(MD5);matcher.setHashIterations(1024);this.setCredentialsMatcher(matcher);}/*** 认证方法只需要完成用户名校验即可密码校验由Shiro内部完成* param token 用户传入的用户名和密码* return* throws AuthenticationException*/Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//1. 基于Token获取用户名String username (String) token.getPrincipal();//2. 判断用户名非空if(StringUtils.isEmpty(username)){// 返回null会默认抛出一个异常org.apache.shiro.authc.UnknownAccountExceptionreturn null;}//3. 如果用户名不为null基于用户名查询用户信息User user this.findUserByUsername(username);//4. 判断user对象是否为nullif(user null){return null;}//5. 声明AuthenticationInfo对象并填充用户信息SimpleAuthenticationInfo info new SimpleAuthenticationInfo(user,user.getPassword(),CustomRealm!!);// 设置盐info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));//6. 返回inforeturn info;}// 模拟数据库操作private User findUserByUsername(String username) {if(admin.equals(username)){User user new User();user.setId(1);user.setUsername(admin);user.setPassword(1ebc4dcaf1e21b814ece65f27531f1a9);user.setSalt(weruiothergjkdfnbgjkdfngjkdf);return user;}return null;}重写doGetAuthorizationInfo方法授权// 授权方法授权是在认证之后的操作
Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//1. 获取认证用户的信息User user (User) principals.getPrimaryPrincipal();//2. 基于用户信息获取当前用户拥有的角色。SetString roleSet this.findRolesByUser();//3. 基于用户拥有的角色查询权限信息SetString permSet this.findPermsByRoleSet(roleSet);//4. 声明AuthorizationInfo对象作为返回值传入角色信息和权限信息SimpleAuthorizationInfo info new SimpleAuthorizationInfo();info.setRoles(roleSet);info.setStringPermissions(permSet);//5. 返回return info;
}private SetString findPermsByRoleSet(SetString roleSet) {SetString set new HashSet();set.add(user:add);set.add(user:update);return set;
}private SetString findRolesByUser() {SetString set new HashSet();set.add(超级管理员);set.add(运营);return set;
}