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

怎么注册自己的微信小程序西安seo按天收费

怎么注册自己的微信小程序,西安seo按天收费,建筑公司名称大全简单大气两个字,南山做网站公司JWTSpringSecurity 6.X 实现登录 JWT token只包含uuid ,token 解析uuid#xff0c;然后某个常量加UUID 从Redis缓存查询用户信息 流程图如下 感谢若依#xff0c;感谢开源#xff0c;能有这么好系统供我学习。 设计数据库#xff0c;部门表#xff0c;用户表#xff0c…JWTSpringSecurity 6.X 实现登录 JWT token只包含uuid ,token 解析uuid然后某个常量加UUID 从Redis缓存查询用户信息 流程图如下 感谢若依感谢开源能有这么好系统供我学习。 设计数据库部门表用户表角色表权限菜单表用户角色表中间表部门角色中间表角色权限菜单表中间表 登录成功返回前端 {msg: 操作成功,code: 200,//用户tokentoken:XXXXX,//菜单权限permissions: [system:user:resetPwd,system:post:list,monitor:operlog:export,monitor:druid:list,system:menu:query,system:dept:remove,system:menu:list,...tool:gen:edit],//角色权限roles: [test2,test1],//用户信息user: {createBy: admin,createTime: 2024-11-28 10:06:12,}//路由信息[{name: System,path: /system,hidden: false,redirect: noRedirect,component: Layout,alwaysShow: true,meta: {title: 系统管理,icon: system,noCache: false,link: null},children: [{name: User,path: user,hidden: false,component: system/user/index,meta: {title: 用户管理,icon: user,noCache: false,link: null}},{name: Log,path: log,hidden: false,redirect: noRedirect,component: ParentView,alwaysShow: true,meta: {title: 日志管理,icon: log,noCache: false,link: null},children: [{name: Operlog,path: operlog,hidden: false,component: monitor/operlog/index,meta: {title: 操作日志,icon: form,noCache: false,link: null}},{name: Logininfor,path: logininfor,hidden: false,component: monitor/logininfor/index,meta: {title: 登录日志,icon: logininfor,noCache: false,link: null}}]}]},{name: Tool,path: /tool,hidden: false,redirect: noRedirect,component: Layout,alwaysShow: true,meta: {title: 系统工具,icon: tool,noCache: false,link: null},children: [{name: Build,path: build,hidden: false,component: tool/build/index,meta: {title: 表单构建,icon: build,noCache: false,link: null}},{name: Gen,path: gen,hidden: false,component: tool/gen/index,meta: {title: 代码生成,icon: code,noCache: false,link: null}},{name: Swagger,path: swagger,hidden: false,component: tool/swagger/index,meta: {title: 系统接口,icon: swagger,noCache: false,link: null}}]},{name: Http://ruoyi.vip,path: http://ruoyi.vip,hidden: false,component: Layout,meta: {title: 若依官网,icon: guide,noCache: false,link: http://ruoyi.vip}}] }所有实体的基类 /*** 实体基类**/ Setter Getter ToString public class BaseEntity {private static final long serialVersionUID 1L;/** 搜索值 */private String searchValue;/** 创建者 */private String createBy;/** 创建时间 */JsonFormat(pattern yyyy-MM-dd HH:mm:ss)private Date createTime;/** 更新者 */private String updateBy;/** 更新时间 */JsonFormat(pattern yyyy-MM-dd HH:mm:ss)private Date updateTime;/** 备注 */ApiModelProperty(value 员工姓名,hidden true)private String remark;/*** 更新数据**/ApiModelProperty(value 员工姓名,hidden true)private boolean update;/*** 新增数据*/ApiModelProperty(value 员工姓名,hidden true)private boolean add;/** 请求参数 */JsonInclude(JsonInclude.Include.NON_EMPTY)ApiModelProperty(value 请求参数,hidden true)private MapString, Object params;}部门实体 /*** 部门表 sys_dept**/ Setter Getter ToString public class SysDept extends BaseEntity {private static final long serialVersionUID 1L;/** 部门ID */private Long deptId;/** 父部门ID */private Long parentId;/** 祖级列表 */private String ancestors;/** 部门名称 */private String deptName;/** 显示顺序 */private Integer orderNum;/** 负责人 */private String leader;/** 联系电话 */private String phone;/** 邮箱 */private String email;/** 部门状态:0正常,1停用 */private String status;/** 删除标志0代表存在 2代表删除 */private String delFlag;/** 父部门名称 */private String parentName;/** 子部门 */private ListSysDept children new ArrayListSysDept(); }用户实体包含角色集合以及所属部门信息 /*** 用户对象 sys_user**/ Setter Getter ToString public class SysUser extends BaseEntity {private static final long serialVersionUID 1L;/** 用户ID */private Long userId;/** 部门ID */private Long deptId;/** 用户账号 */private String userName;/** 用户昵称 */private String nickName;/** 用户邮箱 */private String email;/** 手机号码 */private String phonenumber;/** 用户性别 */private String sex;/** 用户头像 */private String avatar;/** 密码 */private String password;/** 帐号状态0正常 1停用 */private String status;/** 删除标志0代表存在 2代表删除 */private String delFlag;/** 最后登录IP */private String loginIp;/** 最后登录时间 */private Date loginDate;/** 部门对象 */private SysDept dept;/** 角色对象 */private ListSysRole roles;/** 角色组 */private Long[] roleIds;/** 岗位组 */private Long[] postIds;/** 角色ID */private Long roleId;}角色实体包含权限按钮集合,每个按钮对应一个权限system:user:add所以角色还包含权限集合 /*** 角色表 sys_role**/ Setter Getter ToString public class SysRole extends BaseEntity {private static final long serialVersionUID 1L;/** 角色ID */private Long roleId;/** 角色名称 */private String roleName;/** 角色权限 */private String roleKey;/** 角色排序 */private Integer roleSort;/** 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限 */private String dataScope;/** 菜单树选择项是否关联显示 0父子不互相关联显示 1父子互相关联显示 */private boolean menuCheckStrictly;/** 部门树选择项是否关联显示0父子不互相关联显示 1父子互相关联显示 */private boolean deptCheckStrictly;/** 角色状态0正常 1停用 */private String status;/** 删除标志0代表存在 2代表删除 */private String delFlag;/** 用户是否存在此角色标识 默认不存在 */private boolean flag false;/** 菜单组 */private Long[] menuIds;/** 部门组数据权限 */private Long[] deptIds;/** 角色菜单权限 */private SetString permissions;}按钮权限实体,一个按钮下面还有子菜单所以还包含一个菜单集合 /*** 菜单权限表 sys_menu**/ Setter Getter ToString public class SysMenu extends BaseEntity {private static final long serialVersionUID 1L;/** 菜单ID */private Long menuId;/** 菜单名称 */private String menuName;/** 父菜单名称 */private String parentName;/** 父菜单ID */private Long parentId;/** 显示顺序 */private Integer orderNum;/** 路由地址 */private String path;/** 组件路径 */private String component;/** 路由参数 */private String query;/** 路由名称默认和路由地址相同的驼峰格式注意因为vue3版本的router会删除名称相同路由为避免名字的冲突特殊情况可以自定义 */private String routeName;/** 是否为外链0是 1否 */private String isFrame;/** 是否缓存0缓存 1不缓存 */private String isCache;/** 类型M目录 C菜单 F按钮 */private String menuType;/** 显示状态0显示 1隐藏 */private String visible;/** 菜单状态0正常 1停用 */private String status;/** 权限字符串 */private String perms;/** 菜单图标 */private String icon;/** 子菜单 */private ListSysMenu children new ArrayListSysMenu();} 登录用户省份鉴权实体继承UserDetails来源于 spring security 这个用户包含数据库中用户信息而用户信息又包含角色而角色又包含权限菜单所以这个自定义UserDetails实现类包含用户的所有信息 /*** 登录用户身份权限* */ Setter Getter ToString public class LoginUser implements UserDetails {private static final long serialVersionUID 1L;/*** 用户ID*/private Long userId;private String userName;/*** 部门ID*/private Long deptId;/*** 用户唯一标识*/private String token;/*** 登录时间*/private Long loginTime;/*** 过期时间*/private Long expireTime;/*** 登录IP地址*/private String ip;/*** 登录地点*/private String loginLocation;/*** 浏览器类型*/private String browser;/*** 操作系统*/private String os;/*** 权限列表*/private SetString permissions;/*** 用户信息*/private SysUser user;JSONField(serialize false)Overridepublic String getPassword(){return user.getPassword();}Overridepublic String getUsername(){return user.getUserName();}/*** 账户是否未过期,过期无法验证*/JSONField(serialize false)Overridepublic boolean isAccountNonExpired(){return true;}/*** 指定用户是否解锁,锁定的用户无法进行身份验证* * return*/JSONField(serialize false)Overridepublic boolean isAccountNonLocked(){return true;}/*** 指示是否已过期的用户的凭据(密码),过期的凭据防止认证* * return*/JSONField(serialize false)Overridepublic boolean isCredentialsNonExpired(){return true;}/*** 是否可用 ,禁用的用户不能身份验证* * return*/JSONField(serialize false)Overridepublic boolean isEnabled(){return true;}Overridepublic Collection? extends GrantedAuthority getAuthorities(){return null;} }导入spring-security 6.x 依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId /dependencyspring-security 上下文上下文管理对象用来在程序任何地方获取Authentication /*** 自定义 spring security 上下文管理类管理Authentication对象**/ public class AuthenticationContextHolder {//线程池保证线程传递同一个Authentication对象private static final ThreadLocalAuthentication contextHolder new ThreadLocal();public static Authentication getContext(){return contextHolder.get();}public static void setContext(Authentication context){contextHolder.set(context);}public static void clearContext(){contextHolder.remove();} }登录验证 /*** 登录验证** param username 用户名* param password 密码* param code 验证码* param uuid 唯一标识* return 结果*/public String login(String username, String password, String code, String uuid){// 验证码校验validateCaptcha(username, code, uuid);// 登录前置校验loginPreCheck(username, password);// 用户验证Authentication authentication null;try{//创建未认证令牌UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(username, password);AuthenticationContextHolder.setContext(authenticationToken);// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername真正通过用户名查询数据库然后在比较密码//密码一致将UserDetail 对象转换为Authentication 对象authentication authenticationManager.authenticate(authenticationToken);}catch (Exception e){if (e instanceof BadCredentialsException){AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message(user.password.not.match)));throw new UserPasswordNotMatchException();}else{AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));throw new ServiceException(e.getMessage());}}finally{AuthenticationContextHolder.clearContext();}AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message(user.login.success)));LoginUser loginUser (LoginUser) authentication.getPrincipal();recordLoginInfo(loginUser.getUserId());// 验证成功生成tokenreturn tokenService.createToken(loginUser);}自定义UserDetailsServiceImpl就是验证登录密码与从数据库中通过用户名查询的登录密码是否一致一致的话再查询用户所有权限 在把用户信息封装成UserDetail 返回 /*** 用户验证处理**/ Service public class UserDetailsServiceImpl implements UserDetailsService {private static final Logger log LoggerFactory.getLogger(UserDetailsServiceImpl.class);Autowiredprivate ISysUserService userService;Autowiredprivate SysPasswordService passwordService;Autowiredprivate SysPermissionService permissionService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{SysUser user userService.selectUserByUserName(username);if (StringUtils.isNull(user)){log.info(登录用户{} 不存在., username);throw new ServiceException(MessageUtils.message(user.not.exists));}else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())){log.info(登录用户{} 已被删除., username);throw new ServiceException(MessageUtils.message(user.password.delete));}else if (UserStatus.DISABLE.getCode().equals(user.getStatus())){log.info(登录用户{} 已被停用., username);throw new ServiceException(MessageUtils.message(user.blocked));}//验证登录密码与通过登录用户查询到的密码是否一致passwordService.validate(user);//密码验证成功查询用户权限 将用户的所有信息封装成UserDetails 对象在返回return createLoginUser(user);}public UserDetails createLoginUser(SysUser user){//查询用户权限返回 LoginUserreturn new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));} }查询用户权限 /*** 获得用户权限**/ Component public class SysPermissionService {Autowiredprivate ISysRoleService roleService;Autowiredprivate ISysMenuService menuService;/*** 获取角色数据权限** param user 用户信息* return 角色权限信息*/public SetString getRolePermission(SysUser user){SetString roles new HashSetString();// 管理员拥有所有权限if (user.isAdmin()){roles.add(admin);}else{roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));}return roles;}/*** 获取菜单数据权限** param user 用户信息* return 菜单权限信息*/public SetString getMenuPermission(SysUser user){SetString perms new HashSetString();// 管理员拥有所有权限if (user.isAdmin()){perms.add(*:*:*);}else{ListSysRole roles user.getRoles();if (!CollectionUtils.isEmpty(roles)){// 多角色设置permissions属性以便数据权限匹配权限for (SysRole role : roles){if (StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL)){//通过角色获取角色下的菜单权限SetString rolePerms menuService.selectMenuPermsByRoleId(role.getRoleId());role.setPermissions(rolePerms);perms.addAll(rolePerms);}}}else{perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));}}return perms;} } 登录密码验证 /*** 验证登录密码**/ Component public class SysPasswordService {Autowiredprivate RedisCache redisCache;//最大错误登录次数Value(value ${user.password.maxRetryCount})private int maxRetryCount;//最大错误登录次数已满固定时间才能重新登录Value(value ${user.password.lockTime})private int lockTime;/*** 登录账户密码错误次数缓存键名** param username 用户名* return 缓存键key*/private String getCacheKey(String username){return CacheConstants.PWD_ERR_CNT_KEY username;}public void validate(SysUser user){Authentication usernamePasswordAuthenticationToken AuthenticationContextHolder.getContext();String username usernamePasswordAuthenticationToken.getName();String password usernamePasswordAuthenticationToken.getCredentials().toString();//获取用户名密码错误登录次数Integer retryCount redisCache.getCacheObject(getCacheKey(username));if (retryCount null){retryCount 0;}//用户名密码错误登录次数 大于最大登录次数返回提示10分钟后登录if (retryCount Integer.valueOf(maxRetryCount).intValue()){throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);}if (!matches(user, password)){//错误登录失败次数1返回登录失败retryCount retryCount 1;redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);throw new UserPasswordNotMatchException();}else{//登录成功删除错误登录次数clearLoginRecordCache(username);}}public boolean matches(SysUser user, String rawPassword){//上下文中密码与数据库中密码做比较return SecurityUtils.matchesPassword(rawPassword, user.getPassword());}//登录成功删除之前错误登录次数public void clearLoginRecordCache(String loginName){if (redisCache.hasKey(getCacheKey(loginName))){redisCache.deleteObject(getCacheKey(loginName));}} }登录验证完成 创建随机uuid赋值loginUser.token 常量uuid作为key,将用户信息保存redis 常量uuid 加入JWTclaims, 创建加密后的JWT token TokenService 类 /*** 创建令牌** param loginUser 用户信息* return 令牌*/public String createToken(LoginUser loginUser){//生成随机UUIDString token IdUtils.fastUUID();loginUser.setToken(token);setUserAgent(loginUser);//常量uuid作为key,将用户信息保存redisrefreshToken(loginUser);MapString, Object claims new HashMap();claims.put(Constants.LOGIN_USER_KEY, token);//JWT,常量UUID加密创建tokenreturn createToken(claims);}/*** 刷新令牌有效期,第一次就是保存** param loginUser 登录信息*/public void refreshToken(LoginUser loginUser){loginUser.setLoginTime(System.currentTimeMillis());loginUser.setExpireTime(loginUser.getLoginTime() expireTime * MILLIS_MINUTE);// 根据uuid将loginUser缓存String userKey getTokenKey(loginUser.getToken());//某个常量加uuid 作为key,将用户信息保存redisredisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);}/*** JWT从数据声明生成令牌** param claims 数据声明* return 令牌*/private String createToken(MapString, Object claims){String token Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();return token;} 用户请求被JwtAuthenticationTokenFilter过滤 /*** token过滤器 验证token有效性**/ Component public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {Autowiredprivate TokenService tokenService;Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException{//从请求头中获得token,解析token获得uuid,通过uuid 获得redis缓存中loginUser对象LoginUser loginUser tokenService.getLoginUser(request);if (StringUtils.isNotNull(loginUser) StringUtils.isNull(SecurityUtils.getAuthentication())){//验证token 失效时间不足20分钟自动刷新tokenService.verifyToken(loginUser);//创建一个新的已认证令牌UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());//设置已认证令牌的DetailsauthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));//将已认证令牌设置到安全上下文SecurityContextHolder.getContext().setAuthentication(authenticationToken);}//请求转发给过滤器链下一个filter , 如果没有filter那就是请求的资源chain.doFilter(request, response);} }获得请求头里面tokenTokenService类 /*** 获取用户身份信息** return 用户信息*/public LoginUser getLoginUser(HttpServletRequest request){// 获取请求头中tokenString token getToken(request);if (StringUtils.isNotEmpty(token)){try{Claims claims parseToken(token);// 获得token中的uuidString uuid (String) claims.get(Constants.LOGIN_USER_KEY);String userKey getTokenKey(uuid);// 从缓存中获得LoginUser对象LoginUser user redisCache.getCacheObject(userKey);return user;}catch (Exception e){log.error(获取用户信息异常{}, e.getMessage());}}return null;}/*** 获取请求token** param request* return token*/private String getToken(HttpServletRequest request){//从请求头中获取Authorization对应的值String token request.getHeader(header);//判断请求头中是否有Authorization键值对并且值以Bearer开头if (StringUtils.isNotEmpty(token) token.startsWith(Constants.TOKEN_PREFIX)){//将Bearer替换为空串获得真正的token值token token.replace(Constants.TOKEN_PREFIX, );}return token;} 退出操作直接实现LogoutSuccessHandler 然后加入到SecurityConfig 过滤链中 /*** 自定义退出处理类 返回成功* */ Configuration public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {Autowiredprivate TokenService tokenService;/*** 退出处理* * return*/Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)throws IOException, ServletException{LoginUser loginUser tokenService.getLoginUser(request);if (StringUtils.isNotNull(loginUser)){String userName loginUser.getUsername();// 删除用户缓存记录tokenService.delLoginUser(loginUser.getToken());// 记录用户退出日志AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message(user.logout.success)));}ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message(user.logout.success))));} }定义权限上下文持有者将参数放入RequestContextHolder或者从RequestContextHolder取出简单来说就是 属性与当前HTTP请求相关联的方法 /*** 权限信息* */ public class PermissionContextHolder {private static final String PERMISSION_CONTEXT_ATTRIBUTES PERMISSION_CONTEXT;public static void setContext(String permission){RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission,RequestAttributes.SCOPE_REQUEST);}public static String getContext(){return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES,RequestAttributes.SCOPE_REQUEST));} }自定义权限注解就是判断注解上权限值与用户权限是否一致 /**自定义权限注解* * */ Service(ss) public class PermissionService {/*** 验证用户是否具备某权限** param permission 权限字符串* return 用户是否具备某权限*/public boolean hasPermi(String permission){if (StringUtils.isEmpty(permission)){return false;}//从上下文文中获取登录对象LoginUser loginUser SecurityUtils.getLoginUser();if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())){return false;}PermissionContextHolder.setContext(permission);//注解权限与用户权限做比较return hasPermissions(loginUser.getPermissions(), permission);}/*** 验证用户是否不具备某权限与 hasPermi逻辑相反** param permission 权限字符串* return 用户是否不具备某权限*/public boolean lacksPermi(String permission){return hasPermi(permission) ! true;}/*** 验证用户是否具有以下任意一个权限** param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表* return 用户是否具有以下任意一个权限*/public boolean hasAnyPermi(String permissions){if (StringUtils.isEmpty(permissions)){return false;}LoginUser loginUser SecurityUtils.getLoginUser();if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())){return false;}PermissionContextHolder.setContext(permissions);SetString authorities loginUser.getPermissions();for (String permission : permissions.split(Constants.PERMISSION_DELIMETER)){if (permission ! null hasPermissions(authorities, permission)){return true;}}return false;}/*** 判断用户是否拥有某个角色** param role 角色字符串* return 用户是否具备某角色*/public boolean hasRole(String role){if (StringUtils.isEmpty(role)){return false;}LoginUser loginUser SecurityUtils.getLoginUser();if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())){return false;}for (SysRole sysRole : loginUser.getUser().getRoles()){String roleKey sysRole.getRoleKey();if (Constants.SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))){return true;}}return false;}/*** 验证用户是否不具备某角色与 isRole逻辑相反。** param role 角色名称* return 用户是否不具备某角色*/public boolean lacksRole(String role){return hasRole(role) ! true;}/*** 验证用户是否具有以下任意一个角色** param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表* return 用户是否具有以下任意一个角色*/public boolean hasAnyRoles(String roles){if (StringUtils.isEmpty(roles)){return false;}//从上下文中获取LoginUserLoginUser loginUser SecurityUtils.getLoginUser();if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())){return false;}for (String role : roles.split(Constants.ROLE_DELIMETER)){if (hasRole(role)){return true;}}return false;}/*** 判断是否包含权限** param permissions 权限列表* param permission 权限字符串* return 用户是否具备某权限*/private boolean hasPermissions(SetString permissions, String permission){return permissions.contains(Constants.ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));} }自定义注解实现匿名访问 Target({ ElementType.METHOD, ElementType.TYPE }) Retention(RetentionPolicy.RUNTIME) Documented public interface Anonymous { } 注解匿名访问配置类,获得注解方法上的url Configuration public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware {private static final Pattern PATTERN Pattern.compile(\\{(.*?)\\});private ApplicationContext applicationContext;private ListString urls new ArrayList();public String ASTERISK *;Overridepublic void afterPropertiesSet(){RequestMappingHandlerMapping mapping applicationContext.getBean(RequestMappingHandlerMapping.class);MapRequestMappingInfo, HandlerMethod map mapping.getHandlerMethods();map.keySet().forEach(info - {HandlerMethod handlerMethod map.get(info);// 获取方法上边的注解 替代path variable 为 *Anonymous method AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);Optional.ofNullable(method).ifPresent(anonymous - Objects.requireNonNull(info.getPatternsCondition().getPatterns()).forEach(url - urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));// 获取类上边的注解, 替代path variable 为 *Anonymous controller AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);Optional.ofNullable(controller).ifPresent(anonymous - Objects.requireNonNull(info.getPatternsCondition().getPatterns()).forEach(url - urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));});}Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException{this.applicationContext context;}public ListString getUrls(){return urls;}public void setUrls(ListString urls){this.urls urls;} } 使用注解 PostMapping(/url) Anonymous() public AjaxResult anonymouTest(){return AjaxResult.success(操作成功); }SpringSecurity 配置文件 //prePostEnabled true 时PreAuthorize 用于在方法执行前进行权限检查PostAuthorize 用于在方法执行后进行权限检查。 //securedEnabled true 时Secured 用于允许具有特定角色的用户访问。 EnableMethodSecurity(prePostEnabled true, securedEnabled true) Configuration public class SecurityConfig {/*** 自定义用户认证逻辑*/Autowiredprivate UserDetailsService userDetailsService;/*** 认证失败处理类*/Autowiredprivate AuthenticationEntryPointImpl unauthorizedHandler;/*** 退出处理类*/Autowiredprivate LogoutSuccessHandlerImpl logoutSuccessHandler;/*** token认证过滤器*/Autowiredprivate JwtAuthenticationTokenFilter authenticationTokenFilter;/*** 跨域过滤器*/Autowiredprivate CorsFilter corsFilter;/*** 允许匿名访问的地址*/Autowiredprivate PermitAllUrlProperties permitAllUrl;/*** 身份验证实现*/Beanpublic AuthenticationManager authenticationManager(){DaoAuthenticationProvider daoAuthenticationProvider new DaoAuthenticationProvider();daoAuthenticationProvider.setUserDetailsService(userDetailsService);daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());return new ProviderManager(daoAuthenticationProvider);}/*** anyRequest | 匹配所有请求路径* access | SpringEl表达式结果为true时可以访问* anonymous | 匿名可以访问* denyAll | 用户不能访问* fullyAuthenticated | 用户完全认证可以访问非remember-me下自动登录* hasAnyAuthority | 如果有参数参数表示权限则其中任何一个权限可以访问* hasAnyRole | 如果有参数参数表示角色则其中任何一个角色可以访问* hasAuthority | 如果有参数参数表示权限则其权限可以访问* hasIpAddress | 如果有参数参数表示IP地址如果用户IP和参数匹配则可以访问* hasRole | 如果有参数参数表示角色则其角色可以访问* permitAll | 用户可以任意访问* rememberMe | 允许通过remember-me登录的用户访问* authenticated | 用户登录后可访问*/Beanprotected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception{return httpSecurity// CSRF禁用因为不使用session.csrf(csrf - csrf.disable())// 禁用HTTP响应标头.headers((headersCustomizer) - {headersCustomizer.cacheControl(cache - cache.disable()).frameOptions(options - options.sameOrigin());})// 认证失败处理类.exceptionHandling(exception - exception.authenticationEntryPoint(unauthorizedHandler))// 基于token所以不需要session.sessionManagement(session - session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))// 注解标记允许匿名访问的url.authorizeHttpRequests((requests) - {permitAllUrl.getUrls().forEach(url - requests.antMatchers(url).permitAll());// 对于登录login 注册register 验证码captchaImage 允许匿名访问requests.antMatchers(/login, /register, /captchaImage).permitAll()// 静态资源可匿名访问.antMatchers(HttpMethod.GET, /, /*.html, /**/*.html, /**/*.css, /**/*.js, /profile/**).permitAll().antMatchers(/swagger-ui.html, /swagger-resources/**, /webjars/**, /*/api-docs, /druid/**).permitAll()// 除上面外的所有请求全部需要鉴权认证.anyRequest().authenticated();})// 添加Logout filter.logout(logout - logout.logoutUrl(/logout).logoutSuccessHandler(logoutSuccessHandler))// 添加JWT filter.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)// 添加CORS filter.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class).addFilterBefore(corsFilter, LogoutFilter.class).build();}/*** 强散列哈希加密实现*/Beanpublic BCryptPasswordEncoder bCryptPasswordEncoder(){return new BCryptPasswordEncoder();} }
http://www.zqtcl.cn/news/594458/

相关文章:

  • 自己做网站 什么wordpress博客文章加密
  • 怎样做音视频宣传网站wordpress 推送
  • 网站图片上传代码专业的企业进销存软件定制
  • 商品网站模板wordpress文章推荐
  • 十里堡网站建设做吃的教程网站
  • 比较好的源码网站河南网站seo推广
  • 做网站推广什么好网站界面结构
  • 龙岗网站优化常见的渠道推广方式有哪些
  • wordpress 后台乱码成都百度推广优化
  • 大连 响应式网站wordpress保存图片不显示
  • 二手车网站建站网站建设企业建站要求
  • 海山免费网站建设做视频网站如何赚钱
  • 网站增加点击率 怎样做小店面设计装修网
  • 一 美食 视频网站模板下载安装外国优秀网站欣赏
  • 网站服务器部署重庆涪陵网站建设公司
  • php网站开发实践要做网站照片怎么处理
  • 网站短期就业培训班搜集关键词的网站
  • 社区网站开发淘宝网站打算找人做
  • 政务类网站网页管理平台
  • 淘宝联盟微信里做网站花卉市场网站建设基本步骤
  • 做网站广告语网站注册建设
  • 仓山福州网站建设哪个是网站建设里面的
  • 开网站流程开发公司起名
  • 免费建站优化网站基本设置
  • 网站建设需要上传数据库吗seo自己做网站吗
  • 网站制作ppt杭州网站的特点
  • 美丽寮步网站建设价钱杭州网站设计询问蓝韵网络
  • 毕节网站建设公司网站职业技术培训学校
  • 果洛wap网站建设比较好17岁在线观看免费高清完整版
  • 一级a做爰片在线看免播放器网站一个网站突然打不开