网站怎么建设好看淘宝网站开发

当前位置: 首页 > news >正文

网站怎么建设好看,淘宝网站开发,如何做简单网站,在线定制英文名一、权限管理 1.1 什么是权限管理 基本上只要涉及到用户参数的系统都要进行权限管理#xff0c;使用权限管理实现了对用户访问系统的控制#xff0c;不同的用户访问不同的资源。按照安全规则或者安全策略控制用户访问资源#xff0c;而且只能访问被授权的资源 权限管理包括认…  一、权限管理 1.1 什么是权限管理 基本上只要涉及到用户参数的系统都要进行权限管理使用权限管理实现了对用户访问系统的控制不同的用户访问不同的资源。按照安全规则或者安全策略控制用户访问资源而且只能访问被授权的资源 权限管理包括认证和授权两部分当用户访问资源时先对其进行身份的认证认证通过后即可访问已经授权的资源。 1.2 身份认证 用来判断一个用户是否合法的处理过程。用过用户输入的用户名或者口令来和系统中存储进行比较从而认证用户的身份是否正确 对于身份认证也就是之前做的的登录 1.3 授权 用来控制认证过后的用户可以访问哪些资源。用户身份认证后需要给该用户分配可访问的资源如果没有某个资源的权限那么将无法访问 二、Shiro架构 2.1 Shiro的理解 是一个功能强大且易实现的Java安全框架使用Shiro可以执行认证、授权、加密和会话管理。使用Shiro中提供的API可以快速轻松的保护任何程序 Shiro不依赖于WEB即使是一个测试程序也能够使用Shiro中的功能 2.2 Shiro的体系 官方图示 原理 Subject 表示主体外部应用和Subject进行交互。Subject中记录了当前操作用户这个用户可以是一个发送请求的用户也可以是一个运行的程序 Subject在Shiro是一个接口定义了很多认证授权的相关方法外部程序通过Subject进行认证授权Subject又是通过SecurityManager安全管理器就行认证管理 SecurityManager 表示安全管理器是Shiro中的核心用来协调其托管的组件以保证它们能够顺利协同工作。 可以进行会话管理等 Authenticator 表示身份认证器负责执行和响应用户的身份认证尝试的组件。当用户进行登录操作时此组件进行处理 Authorizer 表示授权器负责控制用户在系统中可以访问哪些资源。在访问资源时都需要该组件进行判断当前用户是否拥有这个资源的权限 Realm 表示领域充当Shiro与应用程序的安全数据之间的桥梁或者连接器和DataSource数据源差不多当需要和安全相关的数据如用户账号进行实际交互从而执行认证和授权时Shiro会从应用配置的一个或者多个Realm中查询其中的内容 SecurityManager进行安全认证时需要通过Realm获取到用户权限数据 Realm不只是从数据库取数据还有认证和授权的相关逻辑代码 SessionManager 表示会话管理知道如果创建和管理用户生命周期以便为所欲环境中的用户提供强大的会话体验 不依赖WEB容器所以Shiro可以使用在非WEB应用中也可以将分布式应用的会话集中在一点管理次特征可以使它实现单点登录 SessionDao 表示会话Dao是对session会话操作的一套接口 CacheManager 表示缓存管理器将用户权限存储到缓存中从而提高性能 Cryptography 表示密码管理Shiro中提供了一套加密/解密的组件方便开发 三、Shiro中的认证 3.1 认证中的关键对象 Subject主体 访问系统的每一个用户或者应用程序经过认证的都成为主体 Principal身份信息 是主体Subject进行身份证认证的表示表示必须具有唯一性。比如用户名/手机号/邮箱一个主体Subject中可以有多个身份信息但必须有一个主身份 Credential凭证信息 3.2 认证流程 图示 文字 收集使用者的Principal和Credential 提交进行身份验证 如果验证成功就允许访问否则重试身份证验证或者阻止访问 3.3 环境搭建 引入Shiro依赖 dependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-core/artifactIdversion1.9.1/version /dependency 在resources下创建.ini的配置文件来临时模拟数据库存储用户的身份信息和凭证信息 [users] admin1234 tom222 jack456 编写认证代码 public class ShiroAuthentication {public static void main(String[] args) {// 1.创建SecurityManager安全管理器的实现类DefaultSecurityManager securityManager new DefaultSecurityManager();// 2.将Realm中的数据设置到安全管理器中securityManager.setRealm(new IniRealm(classpath:shiro.ini)); // Realm去读取ini中的主体与凭证信息// 3.将安全管理器设置到全局安全工具类中SecurityUtils.setSecurityManager(securityManager);// 4.获取主体Subject subject SecurityUtils.getSubject();// 5.认证if (!subject.isAuthenticated()) { // 是否已经认证// 如果没有认证过,那么证明该用户第一次登录.收集使用者的身份信息和凭证信息UsernamePasswordToken token new UsernamePasswordToken(admin,1234); // 模拟前台输入// 提交身份信息和凭证信息subject.login(token);}} } 3.4 处理结果 如果提交成功执行后续的逻辑代码提交过程中出现错误那么Shiro将以抛异常的形式声明错误 异常列表 UnknowAccountException  – 未知账号异常【用户名错误】 IncorrectCredentialsException  – 凭证信息异常【密码错误】 LockedAccountException  – 锁定账号异常 ExcessiveAttemptsException  – 过度尝试异常 AuthenticationException  – 身份认证异常 修改以上程序 try {// 开始认证subject.login(token); }catch (UnknownAccountException e){System.out.println(账号错误); }catch (IncorrectCredentialsException e){System.out.println(密码错误); } 3.5 获取主体身份信息与注销 此操作必须保证认证通过 获取主体身份信息 if (subject.isAuthenticated()){ // 认证通过Object principal subject.getPrincipal(); // 6. 获取身份信息System.out.println(principal); // admin } 注销 subject.logout(); 3.6 底层实现 身份信息校验 在SimpleAccountRealm类中的doGetAuthenticationInfo方法判断身份信息是否一致 如果用户名错误那么返回的infonull系统抛出UnknowAccountException异常 密码校验 在AuthenticatingRealm类中的assertCredentialsMatch方法进行密码凭证信息的校验Shiro中凭证信息默认的校验规则是equals 如果密码错误抛出IncorrectCredentialsException异常 3.7 自定义Realm 以后校验用户名肯定不能使用Shiro中定义的需要连接数据库通过用户名查询。所以Shiro中也可以让我们自定义Realm Realm继承图 全部 主要部分 认证方法和授权方法都在AuthorizingRealm定义为抽象方法等待子类继承并重写这两个方法。 SimpleAccountRealm继承了AuthorizingRealm所以这个类里面有认证和授权功能其两个功能对应的方法为 doGetAuthenticationInfo认证 doGetAuthorizationInfo授权 以后自定义的Realm只需要继承AuthorizingRealm然后重写这两个方法 /**

  • 自定义Realm,继承AuthorizingRealm类 */ public class LoginRealm extends AuthorizingRealm {/授权/Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}/认证/Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {return null;} } 在doGetAuthenticationInfo方法中获取用户的身份信息然后校验是否和数据库中的一致 Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// getPrincipal()获取身份信息String username (String) token.getPrincipal();if (admin.equals(username)){// 正确 返回AuthenticationInfo的实现类// 参数:1.当前用户的身份信息 2.验证主体的凭证信息[如果和前台传入的不一致,抛出IncorrectCredentialsException异常] 3.当前Realmreturn new SimpleAuthenticationInfo(username,1234,super.getName());}// 不正确返回一个null, info null 抛出UnknownAccountException异常return null; } 3.8 加密 测试程序 public class MD5Test {public static void main(String[] args) {// 加密Md5Hash md5Hash new Md5Hash(1234);// 加密salt(盐)Md5Hash md5Hash1 new Md5Hash(1234, f5gy);// 加密salt(盐)散列次数Md5Hash md5Hash2 new Md5Hash(1234,f5gy,1024);} } 整合认证 修改认证方法 Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// getPrincipal()获取身份信息String username (String) token.getPrincipal();if (admin.equals(username)){// 正确 返回AuthenticationInfo的实现类/参数:1.当前用户的身份信息2.验证主体的凭证信息[如果和前台传入的不一致,抛出IncorrectCredentialsException异常]3.盐4.当前Realm/String password 75b323294effa42ed07f895f37f9a192;String salt f5gy;return new SimpleAuthenticationInfo(username,password, ByteSource.Util.bytes(salt),super.getName());}// 不正确返回一个null, info null 抛出UnknownAccountException异常return null; } 修改密码比较器 Shiro默认实用的是simpleCredentialsMatcher中的doCredentialsMatcher方法这个方法使用的是equals的方式进行比较密码。 CredentialsMatcher继承图 使用HashedCredentialsMatcher这个类 LoginRealm realm new LoginRealm(); HashedCredentialsMatcher hash new HashedCredentialsMatcher(); // 设置算法 hash.setHashAlgorithmName(MD5); // 设置散列次数 hash.setHashIterations(1024); // 设置到Realm中 realm.setCredentialsMatcher(hash); 四、Shiro中的授权 4.1 授权中的关键对象 Who 表示主体主题需要系统中的资源 What 表示资源这个资源可以是一个按钮、菜单等。资源又分为资源实例和资源类型 How 表示权限/许可控制主体对资源的访问 4.2 授权方式 基于角色的访问控制Role-Based Access Control以角色为中心进行权限控制 基于资源的访问控制Resource-Based Access Control以资源为中心进行权限控制 4.3 权限字符串 权限字符串的规则资源标识符:操作意思是对哪个资源进行哪些操作。:是分割符权限字符串可以使用来表示通配符 4.4 校验角色 在doGetAuthorizationInfo方法中设置当前主体的角色 Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 获取主题中的身份信息[用户名]String principal (String) principals.getPrimaryPrincipal();// 返回AuthorizationInfo的实现类SimpleAuthorizationInfo info new SimpleAuthorizationInfo();// 给当前主体添加角色info.addRole(admin);info.addRole(user);return info; } 模拟前台测试 if (subject.isAuthenticated()){// 校验单个角色System.out.println(subject.hasRole(admin)); // 是否有admin角色// 校验多个角色System.out.println(subject.hasAllRoles(Arrays.asList(admin, user))); // 是否同时有admin user角色// 校验 多次 角色boolean[] booleans subject.hasRoles(Arrays.asList(admin, user, super));for (boolean b : booleans) {System.out.println(b);} } 4.5 校验权限字符串 在doGetAuthorizationInfo方法中设置当前主体的权限字符串 Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 获取主题中的身份信息[用户名]String principal (String) principals.getPrimaryPrincipal();// 返回AuthorizationInfo的实现类SimpleAuthorizationInfo info new SimpleAuthorizationInfo();// 给当前主体添加权限字符串info.addStringPermission(user:update);info.addStringPermission(product:select);return info; } 模拟前台测试 五、整合SpringBoot 5.1 整合思路 5.2 环境搭建 导入springboot和shiro整合的依赖包 dependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-spring-boot-starter/artifactIdversion1.4.0/version /dependency 创建一个类继承AuthorizingRealm类重写授权和认证方法 public class MyRealm extends AuthorizingRealm {Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {return null;} } 编写shiro和springboot整合的配置 Configuration public class ShiroConfig {Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean();// 将SecurityManager设置到Filter中shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);return shiroFilterFactoryBean;}Beanpublic DefaultWebSecurityManager defaultWebSecurityManager(Realm realm){DefaultWebSecurityManager defaultWebSecurityManager new DefaultWebSecurityManager();// 给安全管理器设置RealmdefaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}Beanpublic Realm Realm(){LoginRealm loginRealm new LoginRealm();return loginRealm;} } 在ShiroFilter过滤器中配置需要拦截的资源URL Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean();// 将SecurityManager设置到Filter中shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//设置受限资源MapString,String map new HashMap();/** authc:该路径资源需要认证和授权*/map.put(/,authc); // /代表所有的资源路径都拦截shiroFilterFactoryBean.setFilterChainDefinitionMap(map);return shiroFilterFactoryBean; } 访问资源跳转到login.jsp修改默认跳转路径 shiroFilterFactoryBean.setLoginUrl(/doLogin);Controller public class IndexController {GetMapping(/doLogin)public String doLogin(){return login;} } 拦截后访问/doLogin路径 5.3 ShiroFilter过滤列表 Shiro中提供了多个默认的过滤器用这些过滤器来控制指定URL路径下的资源 配置缩写 对应过滤器 描述 anon AnonymousFilter 指定URL路径下的资源可以匿名访问 authc FormAuthenticationFilter 指定URL路径下的资源需要认证过后才能访问 authcBasic BasicHttpAuthenticationFilter 指定URL路径下的资源需要basic登录 logout LogoutFilter 注销过滤器只需配置对应的URL路径即可实现 noSessionCreation NoSessionCreationFilter 禁止创建Session会话 perms PermissionsAuthorizationFilter 需要有该URL资源对应的权限字符串才能访问 port PortFilter 指定某个端口可以访问 rest HttpMethodPermissionFilter 将HTTP请求转换成相对应的动词来构建权限字符串 roles RolesAuthorizationFilter 需要有指定角色才能访问 ssl SslFilter 需要https请求才能访问 user UserFilter 需要已登录或者记住我的用户才能访问 六、连接数据库完成认证 6.1 注册 表设计 注册页面 !DOCTYPE html html langenheadmeta charsetUTF-8titleTitle/title/headbodyh1注册页面/h1hrform action/user/register methodpost用户名 : input typetext nameusernamebr密码 : input typepassword namepassword brinput typesubmit value注册/form/body /html 实体类POJO Data public class User {private Long id;private String username;private String password;private String salt; } 编写Controller调用service处理业务逻辑 Controller RequestMapping(/user) public class UserController {Autowiredprivate UserService userService;GetMapping(/doRegister)public String doRegister(){return register;}PostMapping(/register)public String register(User user){int count userService.register(user);if (count 0)return redirect:/doLogin;elsereturn redirect:/doRegister;} } 在ShiroFilter放过这些URL路径 map.put(/user/register,anon); map.put(/user/doRegister,anon); service中完成加密和散列盐调用Mapper完成注册 Service public class UserServiceImpl implements UserService {Autowiredprivate UserMapper userMapper;Overridepublic int register(User user) {String salt ga*n;Md5Hash md5Hash new Md5Hash(user.getPassword(),salt,1024);user.setPassword(md5Hash.toHex());user.setSalt(salt);return userMapper.insert(user);} } Mapper接口和SQL语句 public interface UserMapper {int insert(User user); } mapper namespacecom.jiuxiao.mapper.UserMapperinsert idinsertinsert into t_user(id,username,password,salt) values(null,#{username},#{password},#{salt})/insert /mapper 启动类上添加MapperScan注解扫描Mapper包 SpringBootApplication MapperScan(com.jiuxiao.mapper) public class ShiroApp {public static void main(String[] args) {SpringApplication.run(ShiroApp.class,args);} } 注册页面输入用户信息后完成注册 6.2 认证 在Shiro配置中修改密码比较器 Bean public Realm realm(){LoginRealm loginRealm new LoginRealm();HashedCredentialsMatcher matcher new HashedCredentialsMatcher();matcher.setHashAlgorithmName(MD5);matcher.setHashIterations(1024);loginRealm.setCredentialsMatcher(matcher);return loginRealm; } 在自定义的Realm的doGetAuthenticationInfo方法中编写认证逻辑 Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {Autowiredprivate UserService userService;// 获取主体中的身份信息String principal (String) authenticationToken.getPrincipal();// 调用service查询数据库User user userService.selectByUsername(principal);if (!ObjectUtils.isEmpty(user)){// 如果可以查询到校验密码return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), ByteSource.Util.bytes(user.getSalt()),super.getName());}// 查询不到直接返回nullreturn null; } service调用Mapper Override public User selectByUsername(String principal) {return userMapper.selectByUsername(principal); } Mapper接口与SQL语句 User selectByUsername(String principal); select idselectByUsername resultTypecom.jiuxiao.pojo.Userselect * from t_user where username #{username} /select 登录页面代码 !DOCTYPE html html langenheadmeta charsetUTF-8title\(Title\)/title/headbodyh1登录页面/h1hrform action/user/login methodpost用户名: input typetext nameusername br密码: input typepassword namepassword brinput typesubmit value登录/form/body /html 在Controller中编写对应URL封装token并处理异常结果 Controller RequestMapping(/user) public class UserController {PostMapping(/login)public String login(String username,String password){Subject subject SecurityUtils.getSubject();UsernamePasswordToken token new UsernamePasswordToken(username, password);try {subject.login(token);return index; // 登陆成功跳转到首页} catch (UnknownAccountException e) {e.printStackTrace();System.out.println(用户名错误);}catch (IncorrectCredentialsException e){e.printStackTrace();System.out.println(密码错误);}return login; // 登录失败跳转到登录页面} } 首页代码 !DOCTYPE html html langen headmeta charsetUTF-8title\(Title\)/title /head bodyh1首页/h1hrullia href用户管理/a/lilia href商品管理/a/lilia href菜单管理/a/lilia href物流管理/a/li/ul /body /html 在ShiroFilter过滤器中放过登录URL map.put(/user/login,anon); 页面登录成功后进入到index.html 6.3 注销 ① 配置方式 在ShiroFilter过滤器中添加注销的URL map.put(/user/logout,logout); 在页面直接输入这个URL即可注销 ② 代码方式 调用subject的logout方法完成注销页面访问该Controller的URL 七、授权的基本使用 7.1 校验角色 在自定义的Realm的doGetAuthorizationInfo方法中给当前主体赋予角色 Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {// 获取主体中的身份信息String principal (String) principalCollection.getPrimaryPrincipal();if (jiuxiao.equals(principal)){ // 给jiuxiao用户赋予admin和user角色SimpleAuthorizationInfo simpleAuthorizationInfo new SimpleAuthorizationInfo();// 增加admin和user角色simpleAuthorizationInfo.addRole(admin);simpleAuthorizationInfo.addRole(user);return simpleAuthorizationInfo;}return null; } ① 编码方式 单个角色使用subject中的hasRole方法 Controller RequestMapping(/user) public class UserController {GetMapping(/save)ResponseBodypublic String save(){Subject subject SecurityUtils.getSubject();if (!subject.hasRole(admin)) { // 校验当前角色是否有admin这个角色return 权限不足;}else{return 访问成功;   }} } 多个角色使用subject中的hasAllRoles方法【这些角色都有才能访问】 Controller RequestMapping(/user) public class UserController {GetMapping(/save)ResponseBodypublic String save(){ListString roles Arrays.asList(admin, user);if (SecurityUtils.getSubject().hasAllRoles(roles)) {return 访问成功;}else{return 权限不足;}} } ② 注解方式 单个角色直接在注解参数中写入对应的角色即可 Controller RequestMapping(/user) public class UserController {GetMapping(/save)ResponseBodyRequiresRoles(admin)public String save(){return 访问成功;} } 多个角色在注解中以数组的形式写入多个角色【这些角色都有才能访问】 GetMapping(/save) ResponseBody RequiresRoles(value {admin,user}) public String save(){return 访问成功; } 7.2 校验权限字符串 在自定义的Realm的doGetAuthorizationInfo方法中给当前主体赋予权限字符串 Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String principal (String) principalCollection.getPrimaryPrincipal();System.out.println(执行授权principal);if (jiuxiao.equals(principal)){SimpleAuthorizationInfo simpleAuthorizationInfo new SimpleAuthorizationInfo();// 添加权限字符串simpleAuthorizationInfo.addStringPermission(user:update);simpleAuthorizationInfo.addStringPermission(product:create);return simpleAuthorizationInfo;}return null; } ① 编码方式 调用subject中的isPermittedAll方法参数为可变长参数可以传一个或者多个【如果是多个那么这个主体需要拥有参数里面所有的权限字符串才能访问】 Controller RequestMapping(/user) public class UserController {GetMapping(/save)ResponseBodypublic String save(){Subject subject SecurityUtils.getSubject();// if (subject.isPermittedAll(user:update)){ // 判断当前主体使用拥有对user资源的001实例的更新操作if (subject.isPermittedAll(user:update,product:update)){return 访问成功;}else{return 权限不足;}} } ② 注解方式 单个权限字符串直接在注解参数中写入需要校验的权限字符串即可 GetMapping(/save) ResponseBody RequiresPermissions(user:update) public String save(){return 访问成功; } 多个权限字符串在注解中以数组的形式写入多个权限字符串【当前主体主要拥有这些权限字符串才能访问】 GetMapping(/save) ResponseBody RequiresPermissions(value {user:update,product:create}) public String save(){return 访问成功; } ③ 配置方式 在ShiroFilter过滤器使用perms进行权限的校验 map.put(/user/save,perms[user:update,product:delete]); // 数组中添加权限字符串 如果权限不足页面抛出401错误 在ShiroFilter中定义权限不足后跳转的URL 注意定义权限不足跳转URL的方式只限制配置方式别的方式都不能使用权限不足时会抛出AuthorizationException异常 八、连接数据库完成授权 8.1 表设计 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0; – —————————- – Table structure for role_perms – —————————- DROP TABLE IF EXISTS role_perms; CREATE TABLE role_perms  (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,roleid int(11) NULL DEFAULT NULL COMMENT 角色id,permid int(11) NULL DEFAULT NULL COMMENT 权限id,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB AUTO_INCREMENT 1 CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci ROW_FORMAT Dynamic;– —————————- – Table structure for role_user – —————————- DROP TABLE IF EXISTS role_user; CREATE TABLE role_user  (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,roleid int(11) NULL DEFAULT NULL COMMENT 角色id,userid int(11) NULL DEFAULT NULL COMMENT 用户id,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB AUTO_INCREMENT 1 CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci ROW_FORMAT Dynamic;– —————————- – Table structure for t_perms – —————————- DROP TABLE IF EXISTS t_perms; CREATE TABLE t_perms  (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,perm varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT 权限字符串,url varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT 资源URL,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB AUTO_INCREMENT 1 CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci ROW_FORMAT Dynamic;– —————————- – Table structure for t_role – —————————- DROP TABLE IF EXISTS t_role; CREATE TABLE t_role  (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT 角色,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB AUTO_INCREMENT 4 CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci ROW_FORMAT Dynamic;– —————————- – Table structure for t_user – —————————- DROP TABLE IF EXISTS t_user; CREATE TABLE t_user  (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键,username varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT 用户名(身份信息),password varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT 密码(凭证信息),salt varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT 盐,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB AUTO_INCREMENT 3 CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci ROW_FORMAT Dynamic;SET FOREIGN_KEY_CHECKS 1; 8.2 POJO User Data public class User {private Long id;private String username;private String password;private String salt;private ListRole roles; } Role Data public class Role {private Integer id;private String name;private ListPerms perms; } Perms Data public class Perms {private Integer id;private String perm;private String url; } 8.3 授权角色 Mapper接口与SQL语句 ListRole selectRoleNameByUserId(String username); select idselectRoleNameByUserId resultTypecom.jiuxiao.pojo.Roleselect r.id,r.namefrom t_user uleft join role_user ru on ru.userid u.idleft join t_role r on r.id ru.roleidwhere u.username #{username} /select Service Override public ListRole getRoleNameByUsername(String username) {return userMapper.selectRoleNameByUsername(username); } 自定义Realm中进行授权 Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String principal (String) principalCollection.getPrimaryPrincipal();ListRole roles userService.getRoleNameByUsername(principal);if(!CollectionUtils.isEmpty(roles)){SimpleAuthorizationInfo simpleAuthorizationInfo new SimpleAuthorizationInfo();roles.forEach(role- simpleAuthorizationInfo.addRole(role.getName()));return simpleAuthorizationInfo;}return null; } 8.4 授权字符串 Mapper接口与SQL语句  ListString selectPermByRoleId(Integer id); select idselectPermByRoleId resultTypestringselect p.permfrom t_role rleft join role_perms rp on r.id rp.roleidleft join t_perms p on rp.permid p.idwhere r.id #{id} /select Service Override public ListString getPermByRoleId(Integer id) {return userMapper.selectPermByRoleId(id); } 自定义Realm进行授权 Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String principal (String) principalCollection.getPrimaryPrincipal();ListRole roles userService.getRoleNameByUsername(principal);if(!CollectionUtils.isEmpty(roles)){SimpleAuthorizationInfo simpleAuthorizationInfo new SimpleAuthorizationInfo();roles.forEach(role- simpleAuthorizationInfo.addRole(role.getName()));roles.forEach(role-{ListString perms userService.getPermByRoleId(role.getId());simpleAuthorizationInfo.addStringPermissions(perms);});return simpleAuthorizationInfo;}return null; } 九、Shiro与thymeleaf整合 9.1 导入依赖 dependencygroupIdcom.github.theborakompanioni/groupIdartifactIdthymeleaf-extras-shiro/artifactIdversion2.0.0/version /dependency 9.2 配置方言 Bean public ShiroDialect shiroDialect(){return new ShiroDialect(); } 9.3 引入工作空间 html langen xmlns:shirohttp://www.pollix.at/thymeleaf/shiro 9.4 常用标签使用 !– 验证当前用户是否为访客即未认证的用户 – p shiro:guest未认证/p!– 认证通过或者已经记住我的用户 – p shiro:userhello/p!– 认证通过的用户 – p shiro:authenticatedhello/p!– 输出当前用户信息通常为账号登录信息 – p shiro:principal/p!– 判断当前用户是否拥有该角色 – p shiro:hasRoleadmin拥有该角色/p!– 当前用户没有该角色认证通过 – p shiro:lacksRoleuser没有改角色/p!– 判断当前用户是否拥有以下所有角色 – p shiro:hasAllRolesadmin,user/p!– 判断当前用户是否拥有以下任意一个角色 – p shiro:hasAnyRolesadmin,user/p!– 判断当前用户是否拥有以下权限字符串 – p shiro:hasPermissionuser:add/p!– 当前用户没有该权限字符串认证通过 – p shiro:lacksPermissionuser:add/p