电商网站设计规范,建一个公司网站要多少钱,淄博网站建设公司哪家好,wordpress注册页面地址文章目录 前言一、shiro简介二、环境搭建2.1.数据库2.1.1user用户表2.1.2user_role用户角色关系表2.1.3role角色表2.1.4role_permission角色权限关系表2.1.5permission权限表 2.2导坐标2.3实体类2.3.1User2.3.2Role2.3.3Permission 2.4MVC三层2.4.1User2.4.1.1mapper层2.4.1.2s… 文章目录 前言一、shiro简介二、环境搭建2.1.数据库2.1.1user用户表2.1.2user_role用户角色关系表2.1.3role角色表2.1.4role_permission角色权限关系表2.1.5permission权限表 2.2导坐标2.3实体类2.3.1User2.3.2Role2.3.3Permission 2.4MVC三层2.4.1User2.4.1.1mapper层2.4.1.2service层2.4.1.3controller层 2.4.2Role2.4.2.1mapper层2.4.2.2service层2.4.2.3controller层 2.3.3Permission2.4.3.1mapper层2.4.3.2service层2.4.3.3controller层 2.5.加密工具类2.6.全局异常处理器2.7自定义Realm2.8shiro配置类 三、案例演示3.1 登录认证3.2 权限认证 总结 前言
近期对Springboot框架的学习中为了更好的学习理解Springsecurity中间件先学习了一下“老派”的shiro安全框架本文章将通过注解的方式实现基础的用户认证和角色授权案例
一、shiro简介
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
二、环境搭建
2.1.数据库
2.1.1user用户表 2.1.2user_role用户角色关系表 2.1.3role角色表 2.1.4role_permission角色权限关系表 2.1.5permission权限表 2.2导坐标
propertiesjava.version1.8/java.version!--shiro--shiro.version1.3.2/shiro.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-logging/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.29/version/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.4.3/version/dependency!-- SECURITY begin --dependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-core/artifactIdversion${shiro.version}/version/dependencydependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-spring/artifactIdversion${shiro.version}/version/dependencydependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-web/artifactIdversion${shiro.version}/version/dependencydependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-ehcache/artifactIdversion${shiro.version}/version/dependency!-- SECURITY end --/dependencies2.3实体类
2.3.1User
TableName(pe_user)
Data
AllArgsConstructor
NoArgsConstructor
public class User {TableId(value id,type IdType.AUTO)private int id;private String username;private String password;private String salt;TableField(exist false)private SetRole roles;
}2.3.2Role
TableName(pe_role)
Data
AllArgsConstructor
NoArgsConstructor
public class Role {TableId(value id,type IdType.AUTO)private int id;private String name;private String code;private String description;TableField(exist false)private SetPermission permissions;
}
2.3.3Permission
TableName(pe_permission)
Data
AllArgsConstructor
NoArgsConstructor
public class Permission {TableId(value id,type IdType.AUTO)private int id;private String name;private String code;private String description;
}2.4MVC三层
2.4.1User
2.4.1.1mapper层
public interface UserMapper extends BaseMapperUser {Select(select * from pe_user where username #{name})User findUserByName(String name);//级联查询Results({Result(column id,property id),Result(column username,property username),Result(column password,property password),Result(column salt,property salt),Result(column id,property roles,manyMany(select com.apesource.shirostudy_demo_05.dao.RoleMapper.findRoleIdsByUserId))})Select(select * from pe_user where id #{id})User findUserDetailById(Param(id) int id);
}2.4.1.2service层
public interface IUserService extends IServiceUser {User findUserByName(String name);User findUserDetailById(int id);
}Service
SuppressWarnings(all)
public class UserServiceImp extends ServiceImplUserMapper, User implements IUserService {AutowiredUserMapper userMapper;AutowiredIRoleService roleService;Overridepublic User findUserByName(String name) {User user userMapper.findUserByName(name);return user;}Overridepublic User findUserDetailById(int id) {//根据userid查询userUser user userMapper.findUserDetailById(id);//返回return user;}
}2.4.1.3controller层
RestController
public class UserController {Autowiredprivate IUserService userService;//个人主页RequiresPermissions(user-home)RequestMapping(value /user/home)public String home() {return 访问个人主页成功;}//根据名字查询用户基本信息RequiresPermissions(user-find)RequestMapping(value /user/userByName/{name})public String findUserByName(PathVariable String name) {System.out.println(name);User user userService.findUserByName(name);return user.toString();}//更新RequiresPermissions(user-update)RequestMapping(value /user/{id}, method RequestMethod.PUT)public String update(PathVariable String id) {return 更新用户成功;}//删除RequiresPermissions(user-delete)RequestMapping(value /user/{id}, method RequestMethod.DELETE)public String delete(PathVariable String id) {return 删除用户成功;}//根据id查询用户详细信息RequiresPermissions(user-find)RequestMapping(value /user/userById/{id})public String findUserDetailById(PathVariable int id) {return userService.findUserDetailById(id).toString();}//登录页面RequestMapping(value /login)public String login(User user) {try {//1.构造登录令牌UsernamePasswordToken token new UsernamePasswordToken(user.getUsername(), user.getPassword());//2.//2.获取subjectSubject subject SecurityUtils.getSubject();//3.调用subject进行登录subject.login(token);return 登录成功;} catch (AuthenticationException e) {return 用户名或密码错误;}}//未登陆与未授权页面RequestMapping(value /autherror)public String autherror() {return 未登录;}}2.4.2Role
2.4.2.1mapper层
public interface RoleMapper extends BaseMapperRole {Results({Result(column id,property id),Result(column name,property name),Result(column code,property code),Result(column description,property description),Result(column id,property permissions,many Many(select com.apesource.shirostudy_demo_05.dao.PermissionMapper.findPermissionIdsByRoleId))})Select(SELECT * FROM pe_role WHERE id IN (SELECT role_id FROM pe_user_role WHERE user_id #{id}))SetRole findRoleIdsByUserId(int id);
}2.4.2.2service层
public interface IRoleService extends IServiceRole {SetRole findRoleIdsByUserId(int id);
}
Service
SuppressWarnings(all)
public class RoleServiceImp extends ServiceImplRoleMapper, Role implements IRoleService {AutowiredRoleMapper roleMapper;AutowiredIPermissionService permissionService;Overridepublic SetRole findRoleIdsByUserId(int id) {SetRole roles roleMapper.findRoleIdsByUserId(id);return roles;}
}2.4.2.3controller层 由于不演示无。 2.3.3Permission
2.4.3.1mapper层
public interface PermissionMapper extends BaseMapperPermission {Results({Result(column id,property id),Result(column name,property name),Result(column code,property code),Result(column description,property description),})Select(SELECT * FROM pe_permission WHERE id IN (SELECT permission_id FROM pe_role_permission WHERE role_id #{id} ) )SetPermission findPermissionIdsByRoleId(int id);
}2.4.3.2service层
public interface IPermissionService extends IServicePermission {SetPermission findPermissionIdsByRoleId(int id);
}
Service
public class PermissionServiceImp extends ServiceImplPermissionMapper, Permission implements IPermissionService {Autowired(required false)PermissionMapper permissionMapper;Overridepublic SetPermission findPermissionIdsByRoleId(int id) {SetPermission permissionIds permissionMapper.findPermissionIdsByRoleId(id);return permissionIds;}
}2.4.3.3controller层 由于不演示无。 2.5.加密工具类
public class DigestsUtil {public static final String SHA1 SHA-1;public static final Integer COUNTS 369;/*** Description sha1方法* param input 需要散列字符串* param salt 盐字符串* return*/public static String show(String input, String salt) {return new SimpleHash(SHA1, input, salt,COUNTS).toString();}/*** Description 随机获得salt字符串* return*/public static String generateSalt(){SecureRandomNumberGenerator randomNumberGenerator new SecureRandomNumberGenerator();return randomNumberGenerator.nextBytes().toHex();}/*** Description 生成密码字符密文和salt密文* param* return*/public static MapString,String entryptPassword(String passwordPlain) {MapString,String map new HashMap();String salt generateSalt();String password show(passwordPlain,salt);map.put(salt, salt);map.put(password, password);return map;}
}2.6.全局异常处理器
ControllerAdvice
public class BaseExceptionHandler {ExceptionHandler(value AuthorizationException.class)ResponseBodypublic String error(HttpServletRequest request, HttpServletResponse response, AuthorizationException e){return 未授权;}
}2.7自定义Realm
public class MyRealm extends AuthorizingRealm {AutowiredIUserService userService;Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {int userId (int) principalCollection.getPrimaryPrincipal();User user userService.findUserDetailById(userId);SetString roles new HashSet();SetString permissions new HashSet();user.getRoles().stream().forEach(role - {roles.add(role.getCode());role.getPermissions().stream().forEach(permission - {permissions.add(permission.getCode());});});SimpleAuthorizationInfo info new SimpleAuthorizationInfo();info.addRoles(roles);info.addStringPermissions(permissions);return info;}/*** 认证方法* 参数传递的用户名密码*/Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//1.获取登录的用户名密码tokenUsernamePasswordToken token (UsernamePasswordToken) authenticationToken;String username token.getUsername();//2.根据用户名查询数据库//mybatis情景下:user对象中包含IDnamepwd(匿名)User user userService.findUserByName(username);if(user ! null){SimpleAuthenticationInfo info new SimpleAuthenticationInfo(user.getId(),user.getPassword(), ByteSource.Util.bytes(user.getSalt()),myRealm);return info;}return null;}/*** Description 自定义密码比较器* param* return* bean标签 init-method属性*/PostConstructpublic void initCredentialsMatcher() {//指定密码算法HashedCredentialsMatcher hashedCredentialsMatcher new HashedCredentialsMatcher(DigestsUtil.SHA1);//指定迭代次数hashedCredentialsMatcher.setHashIterations(DigestsUtil.COUNTS);//生效密码比较器setCredentialsMatcher(hashedCredentialsMatcher);}
}2.8shiro配置类
Configuration
public class ShiroConfiguration {/*** 1.创建shiro自带cookie对象*/Beanpublic SimpleCookie sessionIdCookie(){SimpleCookie simpleCookie new SimpleCookie();simpleCookie.setName(ShiroSession);return simpleCookie;}//2.创建realmBeanpublic MyRealm getRealm(){return new MyRealm();}/*** 3.创建会话管理器*/Beanpublic DefaultWebSessionManager sessionManager(){DefaultWebSessionManager sessionManager new DefaultWebSessionManager();sessionManager.setSessionValidationSchedulerEnabled(false);sessionManager.setSessionIdCookieEnabled(true);sessionManager.setSessionIdCookie(sessionIdCookie());sessionManager.setGlobalSessionTimeout(3600000);return sessionManager;}//4.创建安全管理器Beanpublic SecurityManager defaultWebSecurityManager() {DefaultWebSecurityManager securityManager new DefaultWebSecurityManager();securityManager.setRealm(getRealm());securityManager.setSessionManager(sessionManager());return securityManager;}/*** 5.保证实现了Shiro内部lifecycle函数的bean执行*/Bean(name lifecycleBeanPostProcessor)public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}/*** 6.开启对shiro注解的支持* AOP式方法级权限检查*/BeanDependsOn(lifecycleBeanPostProcessor)public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator new DefaultAdvisorAutoProxyCreator();defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);return defaultAdvisorAutoProxyCreator;}/*** 7.配合DefaultAdvisorAutoProxyCreator事项注解权限校验*/Beanpublic AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager());return authorizationAttributeSourceAdvisor;}//8.配置shiro的过滤器工厂再web程序中shiro进行权限控制全部是通过一组过滤器集合进行控制Beanpublic ShiroFilterFactoryBean shiroFilter() {//1.创建过滤器工厂ShiroFilterFactoryBean filterFactory new ShiroFilterFactoryBean();//2.设置安全管理器filterFactory.setSecurityManager(defaultWebSecurityManager());//3.通用配置跳转登录页面为授权跳转的页面filterFactory.setLoginUrl(/autherror);//跳转url地址//4.设置过滤器集合//key 拦截的url地址//value 过滤器类型MapString,String filterMap new LinkedHashMap();//key请求规则 value过滤器名称filterMap.put(/login,anon);//当前请求地址可以匿名访问filterMap.put(/user/**,authc);//当前请求地址必须认证之后可以访问//在过滤器工程内设置系统过滤器filterFactory.setFilterChainDefinitionMap(filterMap);return filterFactory;}}
三、案例演示 用户密码均是123456加密后保存至数据库 3.1 登录认证 成功登录 失败登录 3.2 权限认证 由于刚刚登录的信息有管理员和员工的身份所以其所有功能都能使用。 有权限时 无权限时 无权限时会被全局异常处理器拦截并作出响应的响应。 总结
通过对shrio的学习更好的理解了安全认证以及鉴权授权的流程大概了解了安全认证的机制对我之后学习理解Springsecurity有更好的帮助。