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

长沙的企业网站建设大数据营销方式有哪些

长沙的企业网站建设,大数据营销方式有哪些,忽悠别人做商城网站,wordpress评论可见内容简介 Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro#xff0c;它提供了更丰富的功能#xff0c;社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多#xff0c;因为相比与Sp…简介 Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro它提供了更丰富的功能社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多因为相比与SpringSecurityShiro的上手更加的简单。 一般Web应用的需要进行认证和授权。 认证验证当前访问系统的是不是本系统的用户并且要确认具体是哪个用户 授权经过认证后判断当前用户是否有权限进行某个操作 而认证和授权也是SpringSecurity作为安全框架的核心功能。 1.快速入门 1.1.引入依赖 !-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactIdversion3.1.8/version /dependency如果是gradle则使用 // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security implementation group: org.springframework.boot, name: spring-boot-starter-security, version: 3.1.8 引入SpringSecurity依赖后再次输入地址都会统一调转到一个登录界面登录用户名是user,密码是在项目启动时输出在控制台 2.SpringBoot整合Redis 我是在Windos环境下安装Redis这里在Windows下启动Redis 需要进入到安装目录库 输入 redis-server.exe redis.windows.conf 2.1.引入依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactIdversion3.1.8/version /dependencyimplementation group: org.springframework.boot, name: spring-boot-starter-data-redis, version: 3.1.82.2.配置Redis 在配置文件中对redis进行配置 # redis相关配置 spring:data:redis:port: 6379host: 127.0.0.12.3.使用Redis Template 2.3.1.将Redis Template注入到Spring容器中 主要是为了 统一管理 Configuration public class RedisTemplateConfig {Bean(sysMyRedisTemplate)public T RedisTemplateString, T redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplateString, T redisTemplate new RedisTemplate();redisTemplate.setConnectionFactory(redisConnectionFactory);RedisSerializerString redisSerializer new StringRedisSerializer();ObjectMapper om new ObjectMapper();// 持久化改动.设置可见性,om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 持久化改动.非final类型的对象把对象类型也序列化进去以便反序列化推测正确的类型om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);// 持久化改动.null字段不显示om.setSerializationInclusion(JsonInclude.Include.NON_NULL);// 持久化改动.POJO无public属性或方法时不报错om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);// 持久化改动.setObjectMapper方法移除.使用构造方法传入ObjectMapperGenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer new GenericJackson2JsonRedisSerializer(om);redisTemplate.setKeySerializer(redisSerializer);redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setHashKeySerializer(redisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;} }2.3.2.RedisTemplate工具类 为了方便使用可以封装一下工具类进行使用 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.BoundSetOperations; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Component;import java.util.*; import java.util.concurrent.TimeUnit;Component public class RedisCache {Autowiredpublic RedisTemplate redisTemplate;/*** 缓存基本的对象Integer、String、实体类等** param key 缓存的键值* param value 缓存的值*/public T void setCacheObject(final String key, final T value) {redisTemplate.opsForValue().set(key, value);}/*** 缓存基本的对象Integer、String、实体类等** param key 缓存的键值* param value 缓存的值* param timeout 时间* param timeUnit 时间颗粒度*/public T void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}/*** 设置有效时间** param key Redis键* param timeout 超时时间* return true设置成功false设置失败*/public boolean expire(final String key, final long timeout) {return expire(key, timeout, TimeUnit.SECONDS);}/*** 设置有效时间** param key Redis键* param timeout 超时时间* param unit 时间单位* return true设置成功false设置失败*/public boolean expire(final String key, final long timeout, final TimeUnit unit) {return redisTemplate.expire(key, timeout, unit);}/*** 获得缓存的基本对象。** param key 缓存键值* return 缓存键值对应的数据*/public T T getCacheObject(final String key) {ValueOperationsString, T operation redisTemplate.opsForValue();return operation.get(key);}/*** 删除单个对象** param key*/public boolean deleteObject(final String key) {return redisTemplate.delete(key);}/*** 删除集合对象** param collection 多个对象* return*/public long deleteObject(final Collection collection) {return redisTemplate.delete(collection);}/*** 缓存List数据** param key 缓存的键值* param dataList 待缓存的List数据* return 缓存的对象*/public T long setCacheList(final String key, final ListT dataList) {Long count redisTemplate.opsForList().rightPushAll(key, dataList);return count null ? 0 : count;}/*** 获得缓存的list对象** param key 缓存的键值* return 缓存键值对应的数据*/public T ListT getCacheList(final String key) {return redisTemplate.opsForList().range(key, 0, -1);}/*** 缓存Set** param key 缓存键值* param dataSet 缓存的数据* return 缓存数据的对象*/public T BoundSetOperationsString, T setCacheSet(final String key, final SetT dataSet) {BoundSetOperationsString, T setOperation redisTemplate.boundSetOps(key);IteratorT it dataSet.iterator();while (it.hasNext()) {setOperation.add(it.next());}return setOperation;}/*** 获得缓存的set** param key* return*/public T SetT getCacheSet(final String key) {return redisTemplate.opsForSet().members(key);}/*** 缓存Map** param key* param dataMap*/public T void setCacheMap(final String key, final MapString, T dataMap) {if (dataMap ! null) {redisTemplate.opsForHash().putAll(key, dataMap);}}/*** 获得缓存的Map** param key* return*/public T MapString, T getCacheMap(final String key) {return redisTemplate.opsForHash().entries(key);}/*** 往Hash中存入数据** param key Redis键* param hKey Hash键* param value 值*/public T void setCacheMapValue(final String key, final String hKey, final T value) {redisTemplate.opsForHash().put(key, hKey, value);}/*** 获取Hash中的数据** param key Redis键* param hKey Hash键* return Hash中的对象*/public T T getCacheMapValue(final String key, final String hKey) {HashOperationsString, String, T opsForHash redisTemplate.opsForHash();return opsForHash.get(key, hKey);}public void incrementCacheMapValue(String key, String hKey, int v) {redisTemplate.opsForHash().increment(key, hKey, v);}/*** 删除Hash中的数据** param key* param hkey*/public void delCacheMapValue(final String key, final String hkey) {HashOperations hashOperations redisTemplate.opsForHash();hashOperations.delete(key, hkey);}/*** 获取多个Hash中的数据** param key Redis键* param hKeys Hash键集合* return Hash对象集合*/public T ListT getMultiCacheMapValue(final String key, final CollectionObject hKeys) {return redisTemplate.opsForHash().multiGet(key, hKeys);}/*** 获得缓存的基本对象列表** param pattern 字符串前缀* return 对象列表*/public CollectionString keys(final String pattern) {return redisTemplate.keys(pattern);} } 2.3.3.测试 测试是否能正常使用 RequestMapping(/redis)public String redis(){redisCache.setCacheObject(test, test);return redisCache.getCacheObject(test).toString();}3.SpringBoot整合JJWT 3.1.引入依赖 !-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -- dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion0.12.5/version /dependency implementation group: io.jsonwebtoken, name: jjwt, version: 0.12.5 3.2.JJW工具类 为了方便使用我们将其封装成一个工具类 由于使用的版本是新版本的JDK 以及 JJWT所以网 这里的工具类 写法会有些出入 /*** JWT Token工具类用于生成和解析JWT Token** Author: Tiam* Date: 2023/10/23 16:38*/ public class TokenUtil {/*** 过期时间(单位:秒)*/public static final int ACCESS_EXPIRE 60 * 60 * 60;/*** 加密算法*/private final static SecureDigestAlgorithmSecretKey, SecretKey ALGORITHM Jwts.SIG.HS256;/*** 私钥 / 生成签名的时候使用的秘钥secret一般可以从本地配置文件中读取。* 切记秘钥不能外露在任何场景都不应该流露出去。* 应该大于等于 256位(长度32及以上的字符串)并且是随机的字符串*/public final static String SECRET secrasdddddddddddddddddddddddddddddddddwqeqeqwewqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqetKey;/*** 秘钥实例*/public static final SecretKey KEY Keys.hmacShaKeyFor(SECRET.getBytes(StandardCharsets.UTF_8));/*** jwt签发者*/private final static String JWT_ISS Tiam;/*** jwt主题*/private final static String SUBJECT Peripherals;/*** 生成访问令牌** param username 用户名* return 访问令牌*/public static String genAccessToken(String username) {// 生成令牌IDString uuid UUID.randomUUID().toString();// 设置过期时间Date expireDate Date.from(Instant.now().plusSeconds(ACCESS_EXPIRE));return Jwts.builder()// 设置头部信息.header().add(typ, JWT).add(alg, HS256).and()// 设置自定义负载信息.claim(username, username).id(uuid) // 令牌ID.expiration(expireDate) // 过期日期.issuedAt(new Date()) // 签发时间.subject(SUBJECT) // 主题.issuer(JWT_ISS) // 签发者.signWith(KEY, ALGORITHM) // 签名.compact();}/*** 获取payload中的用户信息** param token JWT Token* return 用户信息*/public static String getUserFromToken(String token) {String user ;Claims claims parseClaims(token);if (claims ! null) {user (String) claims.get(username);}return user;}/*** 获取JWT令牌的过期时间** param token JWT令牌* return 过期时间的毫秒级时间戳*/public static long getExpirationTime(String token) {Claims claims parseClaims(token);if (claims ! null) {return claims.getExpiration().getTime();}return 0L;}/*** 解析token** param token token* return JwsClaims*/public static JwsClaims parseClaim(String token) {return Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token);}/*** 解析token的头部信息** param token token* return token的头部信息*/public static JwsHeader parseHeader(String token) {return parseClaim(token).getHeader();}/*** 解析token的载荷信息** param token token* return token的载荷信息*/public static Claims parsePayload(String token) {return parseClaim(token).getPayload();}/*** 解析JWT Token中的Claims** param token JWT Token* return Claims*/public static Claims parseClaims(String token) {try {return Jwts.parser().setSigningKey(KEY).build().parseClaimsJws(token).getBody();} catch (Exception e) {return null;}} } 3.3.测试 RequestMapping(/jjwt)public MapString, String jjwt(){MapString, String map new HashMap();String tokenByKey TokenUtil.genAccessToken(hrfan);map.put(encoding, tokenByKey);return map;}4.实战 背景 在企业开发中一个安全的登录授权系统是至关重要的它不仅可以保护用户的隐私信息还能够确保只有经过授权的用户才能够访问特定的资源和功能。这样的系统不仅仅是为了满足用户的安全需求也是为了保护企业的敏感数据和资源免受未经授权的访问和恶意攻击。 首先一个安全的登录授权系统必须具备可靠的身份验证机制。用户需要能够通过输入凭据通常是用户名和密码来验证其身份。这个过程需要保证用户的密码被安全地存储并且在传输过程中使用加密技术保障用户凭据的安全性。 其次授权系统需要根据用户的身份和角色来管理用户对资源和功能的访问权限。不同的用户可能具有不同的角色和权限例如普通用户、管理员、审计员等。系统需要根据用户的角色和权限来限制他们对资源的访问以确保敏感数据不会被未经授权的用户获取。 下面使用SpringSecurity来实现一个简易的登录认证 用户身份验证 登录页面: 我们需要一个登录页面用户可以在该页面输入他们的凭据以进行身份验证。登录页面应该友好且易于理解。身份验证: 用户的用户名和密码应该被验证只有在验证通过后才能进入系统。密码应该以安全的方式存储例如使用哈希算法加密存储。认证失败处理: 如果用户提供的凭据无效则系统应该向用户提供相应的错误消息并允许他们再次尝试登录。 访问控制 受保护资源: 我们的系统将有一些受保护的资源和功能例如管理课程、学生信息等。只有经过身份验证的用户才能访问这些资源。角色和权限: 不同类型的用户应该有不同的角色和权限。例如管理员可能具有管理课程和学生的权限而普通用户可能只能访问课程内容。未经授权的访问: 如果用户尝试访问他们没有权限的资源则系统应该拒绝访问并向用户显示适当的错误消息。 安全性 防范攻击: 我们的系统应该能够防范常见的安全攻击如跨站脚本攻击、SQL注入等。密码安全: 用户的密码不应以明文形式存储在数据库中而应该使用安全的加密算法进行存储。 4.1.创建数据库表 4.1.1.创建用户表 Spring Security要求实现UserDetails接口是为了统一表示用户身份和权限信息以便于在认证和授权过程中使用。UserDetails提供了标准化的用户信息模型包括用户名、密码、权限等使得Spring Security能够与不同的用户信息源集成同时提供灵活性和可定制性。 RBCA模型介绍 RBACRole-Based Access Control模型是一种访问控制模型它基于角色来管理对资源的访问权限。在RBAC模型中用户被分配到不同的角色而每个角色具有特定的权限。这种模型使得权限管理更加灵活和可扩展同时降低了管理的复杂性。 user表代表系统中的用户。role表代表系统中的角色。permission表代表系统中的权限。user_role表用于关联用户与角色。role_permission表用于关联角色与权限。 CREATE TABLE hr_manager.t_sys_my_user (sid VARCHAR ( 50 ) COLLATE pg_catalog.default NOT NULL,user_no VARCHAR ( 50 ) COLLATE pg_catalog.default,user_name VARCHAR ( 50 ) COLLATE pg_catalog.default,password VARCHAR ( 100 ) COLLATE pg_catalog.default,nick_name VARCHAR ( 100 ) COLLATE pg_catalog.default,phone_number VARCHAR ( 50 ) COLLATE pg_catalog.default,email VARCHAR ( 50 ) COLLATE pg_catalog.default,department_id VARCHAR ( 50 ) COLLATE pg_catalog.default,department_name VARCHAR ( 100 ) COLLATE pg_catalog.default,is_admin VARCHAR ( 1 ) COLLATE pg_catalog.default,sex VARCHAR ( 1 ) COLLATE pg_catalog.default,post_id VARCHAR ( 50 ) COLLATE pg_catalog.default,post_name VARCHAR ( 100 ) COLLATE pg_catalog.default,is_account_non_expired bool,is_account_non_locked bool,is_credentials_non_expired bool,is_enabled bool,insert_user VARCHAR ( 50 ) COLLATE pg_catalog.default,insert_time DATE,update_user VARCHAR ( 50 ) COLLATE pg_catalog.default,update_time DATE,license_code VARCHAR ( 20 ) COLLATE pg_catalog.default,CONSTRAINT t_sys_my_user_pkey PRIMARY KEY ( sid ) ); ALTER TABLE hr_manager.t_sys_my_user OWNER TO postgres; COMMENT ON COLUMN hr_manager.t_sys_my_user.sid IS 主键SID; COMMENT ON COLUMN hr_manager.t_sys_my_user.user_no IS 用户登录账号; COMMENT ON COLUMN hr_manager.t_sys_my_user.user_name IS 用户名称; COMMENT ON COLUMN hr_manager.t_sys_my_user.password IS 用户密码; COMMENT ON COLUMN hr_manager.t_sys_my_user.nick_name IS 用户昵称; COMMENT ON COLUMN hr_manager.t_sys_my_user.phone_number IS 手机号码; COMMENT ON COLUMN hr_manager.t_sys_my_user.email IS 邮箱; COMMENT ON COLUMN hr_manager.t_sys_my_user.department_id IS 部门ID; COMMENT ON COLUMN hr_manager.t_sys_my_user.department_name IS 部门名称; COMMENT ON COLUMN hr_manager.t_sys_my_user.is_admin IS 是否为管理员 0 否 1 是; COMMENT ON COLUMN hr_manager.t_sys_my_user.sex IS 性别 0 男 1 女; COMMENT ON COLUMN hr_manager.t_sys_my_user.post_id IS 岗位ID; COMMENT ON COLUMN hr_manager.t_sys_my_user.post_name IS 岗位名称; COMMENT ON COLUMN hr_manager.t_sys_my_user.is_account_non_expired IS 账户是否过期; COMMENT ON COLUMN hr_manager.t_sys_my_user.is_account_non_locked IS 账户是否被锁定; COMMENT ON COLUMN hr_manager.t_sys_my_user.is_credentials_non_expired IS 密码是否过期; COMMENT ON COLUMN hr_manager.t_sys_my_user.is_enabled IS 账户是否可用; COMMENT ON COLUMN hr_manager.t_sys_my_user.insert_user IS 创建人; COMMENT ON COLUMN hr_manager.t_sys_my_user.insert_time IS 创建时间; COMMENT ON COLUMN hr_manager.t_sys_my_user.update_user IS 更新人; COMMENT ON COLUMN hr_manager.t_sys_my_user.update_time IS 更新时间; COMMENT ON COLUMN hr_manager.t_sys_my_user.license_code IS 许可标识;4.1.2.创建权限表 CREATE TABLE hr_manager.t_sys_my_permission (sid VARCHAR ( 50 ) COLLATE pg_catalog.default NOT NULL,parent_id VARCHAR ( 50 ) COLLATE pg_catalog.default,parent_name VARCHAR ( 100 ) COLLATE pg_catalog.default,permission_name VARCHAR ( 100 ) COLLATE pg_catalog.default,permission_code VARCHAR ( 100 ) COLLATE pg_catalog.default,router_path VARCHAR ( 255 ) COLLATE pg_catalog.default,router_name VARCHAR ( 100 ) COLLATE pg_catalog.default,auth_url VARCHAR ( 255 ) COLLATE pg_catalog.default,order_no int4,type VARCHAR ( 1 ) COLLATE pg_catalog.default,icon VARCHAR ( 100 ) COLLATE pg_catalog.default,remark VARCHAR ( 255 ) COLLATE pg_catalog.default,insert_user VARCHAR ( 50 ) COLLATE pg_catalog.default,insert_time DATE,update_user VARCHAR ( 50 ) COLLATE pg_catalog.default,update_time DATE,license_code VARCHAR ( 20 ) COLLATE pg_catalog.default,CONSTRAINT t_sys_my_permission_pkey PRIMARY KEY ( sid ) ); ALTER TABLE hr_manager.t_sys_my_permission OWNER TO postgres; COMMENT ON COLUMN hr_manager.t_sys_my_permission.sid IS 主键SID; COMMENT ON COLUMN hr_manager.t_sys_my_permission.parent_id IS 父节点ID; COMMENT ON COLUMN hr_manager.t_sys_my_permission.parent_name IS 父节点名称; COMMENT ON COLUMN hr_manager.t_sys_my_permission.permission_name IS 权限名称; COMMENT ON COLUMN hr_manager.t_sys_my_permission.permission_code IS 授权标识符; COMMENT ON COLUMN hr_manager.t_sys_my_permission.router_path IS 路由地址; COMMENT ON COLUMN hr_manager.t_sys_my_permission.router_name IS 路由名称; COMMENT ON COLUMN hr_manager.t_sys_my_permission.auth_url IS 授权路径对应文件在项目的地址; COMMENT ON COLUMN hr_manager.t_sys_my_permission.order_no IS 序号用于排序; COMMENT ON COLUMN hr_manager.t_sys_my_permission.type IS 类型 0 目录 1 菜单 2 按钮; COMMENT ON COLUMN hr_manager.t_sys_my_permission.icon IS 图标; COMMENT ON COLUMN hr_manager.t_sys_my_permission.remark IS 备注; COMMENT ON COLUMN hr_manager.t_sys_my_permission.insert_user IS 创建人; COMMENT ON COLUMN hr_manager.t_sys_my_permission.insert_time IS 创建时间; COMMENT ON COLUMN hr_manager.t_sys_my_permission.update_user IS 更新人; COMMENT ON COLUMN hr_manager.t_sys_my_permission.update_time IS 更新时间; COMMENT ON COLUMN hr_manager.t_sys_my_permission.license_code IS 许可标识;4.1.3.创建角色表 CREATE TABLE hr_manager.t_sys_my_role (sid VARCHAR ( 50 ) COLLATE pg_catalog.default NOT NULL,role_name VARCHAR ( 100 ) COLLATE pg_catalog.default,remark VARCHAR ( 255 ) COLLATE pg_catalog.default,insert_user VARCHAR ( 50 ) COLLATE pg_catalog.default,insert_time DATE,update_user VARCHAR ( 50 ) COLLATE pg_catalog.default,update_time DATE,status VARCHAR ( 255 ) COLLATE pg_catalog.default,CONSTRAINT t_sys_my_role_pkey PRIMARY KEY ( sid ) ); ALTER TABLE hr_manager.t_sys_my_role OWNER TO postgres; COMMENT ON COLUMN hr_manager.t_sys_my_role.sid IS 主键SID; COMMENT ON COLUMN hr_manager.t_sys_my_role.role_name IS 角色名称; COMMENT ON COLUMN hr_manager.t_sys_my_role.remark IS 备注; COMMENT ON COLUMN hr_manager.t_sys_my_role.insert_user IS 创建人; COMMENT ON COLUMN hr_manager.t_sys_my_role.insert_time IS 创建时间; COMMENT ON COLUMN hr_manager.t_sys_my_role.update_user IS 更新人; COMMENT ON COLUMN hr_manager.t_sys_my_role.update_time IS 更新时间; COMMENT ON COLUMN hr_manager.t_sys_my_role.status IS 是否使用 0 禁用 1 使用;4.1.4.创建用户角色表 CREATE TABLE hr_manager.t_sys_my_user_role (sid VARCHAR ( 50 ) COLLATE pg_catalog.default NOT NULL,role_sid VARCHAR ( 50 ) COLLATE pg_catalog.default,user_sid VARCHAR ( 50 ) COLLATE pg_catalog.default,insert_user VARCHAR ( 50 ) COLLATE pg_catalog.default,insert_time DATE,CONSTRAINT t_sys_my_user_role_pkey PRIMARY KEY ( sid ) ); ALTER TABLE hr_manager.t_sys_my_user_role OWNER TO postgres; COMMENT ON COLUMN hr_manager.t_sys_my_user_role.sid IS 主键SID; COMMENT ON COLUMN hr_manager.t_sys_my_user_role.role_sid IS 角色SID; COMMENT ON COLUMN hr_manager.t_sys_my_user_role.user_sid IS 用户SID; COMMENT ON COLUMN hr_manager.t_sys_my_user_role.insert_user IS 创建人; COMMENT ON COLUMN hr_manager.t_sys_my_user_role.insert_time IS 创建时间;4.1.5.创建角色权限表 CREATE TABLE hr_manager.t_sys_my_role_permission (sid VARCHAR ( 50 ) COLLATE pg_catalog.default NOT NULL,role_sid VARCHAR ( 50 ) COLLATE pg_catalog.default,permission_sid VARCHAR ( 50 ) COLLATE pg_catalog.default,insert_user VARCHAR ( 50 ) COLLATE pg_catalog.default,insert_time DATE,CONSTRAINT t_sys_my_role_permission_pkey PRIMARY KEY ( sid ) ); ALTER TABLE hr_manager.t_sys_my_role_permission OWNER TO postgres; COMMENT ON COLUMN hr_manager.t_sys_my_role_permission.sid IS 主键SID; COMMENT ON COLUMN hr_manager.t_sys_my_role_permission.role_sid IS 角色SID; COMMENT ON COLUMN hr_manager.t_sys_my_role_permission.permission_sid IS 权限SID; COMMENT ON COLUMN hr_manager.t_sys_my_role_permission.insert_user IS 创建人; COMMENT ON COLUMN hr_manager.t_sys_my_role_permission.insert_time IS 创建时间;4.2.创建实体类 4.2.1.创建用户实体类 Data public class SysMyUser implements Serializable, UserDetails {private static final long serialVersionUID 1L;TableId/*** sid*/private String sid;/*** user_no*/private String userNo;/*** user_name*/private String userName;/*** password*/private String password;/*** nick_name*/private String nickName;/*** phone_number*/private String phoneNumber;/*** email*/private String email;/*** department_id*/private String departmentId;/*** department_name*/private String departmentName;/*** is_admin*/private String isAdmin;/*** sex*/private String sex;/*** post_id*/private String postId;/*** post_name*/private String postName;/*** is_account_non_expired*/private Boolean isAccountNonExpired;/*** is_account_non_locked*/private Boolean isAccountNonLocked;/*** is_credentials_non_expired*/private Boolean isCredentialsNonExpired;/*** is_enabled*/private Boolean isEnabled;/*** insert_user*/private String insertUser;/*** insert_time*/private String insertTime;/*** update_user*/private String updateUser;/*** update_time*/private String updateTime;/*** license_code*/private String licenseCode;/*** 权限列表 就是菜单列表*/TableField(exist false)private ListSysMyPermission permissionList;/*** 认证信息 就是用户配置code*/TableField(exist false)Collection? extends GrantedAuthority authorities;/*** 用户权限信息*/TableField(exist false)private ListString roles;Overridepublic Collection? extends GrantedAuthority getAuthorities() {return authorities;}Overridepublic String getUsername() {return this.userNo;}Overridepublic String getPassword() {return this.password;}Overridepublic boolean isAccountNonExpired() {return this.isAccountNonExpired;}Overridepublic boolean isAccountNonLocked() {return this.isAccountNonLocked;}Overridepublic boolean isCredentialsNonExpired() {return this.isCredentialsNonExpired;}Overridepublic boolean isEnabled() {return this.isEnabled;} }4.2.2.创建权限实体类 Data public class SysMyPermission implements Serializable {private static final long serialVersionUID 1L;TableId/*** sid*/private String sid;/*** parent_id*/private String parentId;/*** parent_name*/private String parentName;/*** permission_name*/private String permissionName;/*** permission_code*/private String permissionCode;/*** router_path*/private String routerPath;/*** router_name*/private String routerName;/*** auth_url*/private String authUrl;/*** order_no*/private String orderNo;/*** type*/private String type;/*** icon*/private String icon;/*** remark*/private String remark;/*** insert_user*/private String insertUser;/*** insert_time*/private String insertTime;/*** update_user*/private String updateUser;/*** update_time*/private String updateTime;/*** license_code*/private String licenseCode;/*** 菜单的子集合*/TableField(exist false)JsonInclude(JsonInclude.Include.NON_NULL)private ListSysMyPermission children new ArrayList(); }4.3.创建Service和Dao 这里就不过多介绍了直接贴上代码 4.3.1.UserService Service public class SysMyUserService {Resourceprivate SysMyUserMapper userMapper;/*** 根据用户id获取用户信息包含用户具备的权限信息* param username 用户信息* return*/public SysMyUser getUserInfoByUserId(String username) {// 获取用户的基础信息SysMyUser userInfo userMapper.getUserInfoByUserId(username);Assert.notNull(userInfo, 用户不存在);// 根据用户id对应的权限信息ListString autorizedList userMapper.getAutorizedListByUserId(userInfo.getSid());;userInfo.setRoles(autorizedList);return userInfo;}/*** 获取加密后的密码 ,使用BCryptPasswordEncoder加密 10次 生成密码* param password 密码* return 加密后的密码*/public String getEncoderPassword(String password) {BCryptPasswordEncoder encoder new BCryptPasswordEncoder(10);String encodePassword encoder.encode(password);return encodePassword;} }4.3.2.UserMapper Repository public interface SysMyUserMapper extends BaseMapperSysMyUser {/*** 根据用户名账号获取用户信息* param username 用户信息* return 用户信息*/SysMyUser getUserInfoByUserId(Param(username) String username);/*** 根据用户id获取用户具备的权限信息* param sid 用户id* return 用户具备的权限信息*/ListString getAutorizedListByUserId(Param(sid) String sid); } 4.3.3.UserMapper.xml ?xml version1.0 encodingUTF-8? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.sys.my.core.user.dao.SysMyUserMapper!-- 根据用户名账号获取用户信息 --select idgetUserInfoByUserId resultTypecom.sys.my.core.user.model.SysMyUserselect * from t_sys_my_user u where u.user_no #{username};/select!-- 根据用户id获取用户具备的权限信息 --select idgetAutorizedListByUserId resultTypejava.lang.Stringselectp.permission_codefrom t_sys_my_role rleft join t_sys_my_user_role ur on ur.role_sid r.sidleft join t_sys_my_role_permission rp on rp.role_sid r.sidleft join t_sys_my_permission p on p.sid rp.permission_sidleft join t_sys_my_user u on u.sid ur.user_sidwhere p.status 1 and r.status 1 and u.sid #{sid};/select /mapper4.3.4.SysMyPermissionService Service public class SysMyPermissionService {private static final Logger logger LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());Resourceprivate SysMyPermissionMapper sysMyPermissionMapper;/*** 根据用户id查询对应的权限* param userId 用户id* return 权限列表*/public ListSysMyPermission getPermissionListByUserId(String userId){// 根据用户ID获取用户对应的权限return sysMyPermissionMapper.getMenuListByUserId(userId);} } 4.3.5.SysMyPermissionMapper Repository public interface SysMyPermissionMapper extends BaseMapperSysMyPermission {/*** 根据用户ID获取用户对应的权限* param userId 用户ID* return 权限列表*/ListSysMyPermission getMenuListByUserId(Param(userId) String userId); } 4.3.6.SysMyPermissionMapper.xml ?xml version1.0 encodingUTF-8? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.sys.my.core.permission.dao.SysMyPermissionMapper!-- 根据用户id获取用户具备的权限信息 --select idgetMenuListByUserId resultTypecom.sys.my.core.permission.model.SysMyPermissionselectp.*from t_sys_my_role rleft join t_sys_my_user_role ur on ur.role_sid r.sidleft join t_sys_my_role_permission rp on rp.role_sid r.sidleft join t_sys_my_permission p on p.sid rp.permission_sidleft join t_sys_my_user u on u.sid ur.user_sidwhere p.status 1 and r.status 1 and u.sid #{userId};/select /mapper4.4.重写UserDetailsService方法 重写 Spring Security 中的 UserDetailsService 接口的主要目的是提供自定义的用户认证逻辑。Spring Security 的 UserDetailsService 负责从数据源通常是数据库中加载用户信息包括用户名、密码和权限等以便进行身份验证。 通常情况下我们需要重写 UserDetailsService 的 loadUserByUsername() 方法该方法接收用户名作为参数并返回一个 UserDetails 对象该对象包含了与用户名对应的用户信息。在实际开发中我们可能需要自定义的用户信息存储方式或者希望在加载用户信息时进行一些特定的逻辑处理比如自定义密码加密方式、从数据库或其他数据源加载用户信息等。 /*** 自定义UserDetailsService 用于认证和授权* 此处把用户的信息和权限交给spring security* spring security会对用户的信息和权限信息进行管理* author hffan* serDetailService接口主要定义了一个方法 l* oadUserByUsername(String username)用于完成用户信息的查询* 其中username就是登录时的登录名称登录认证时需要自定义一个实现类实现UserDetailService接口* 完成数据库查询该接口返回UserDetail。*/ Component(customerUserDetailsService) public class CustomerUserDetailsService implements UserDetailsService {Resourceprivate SysMyUserService userService;Resourceprivate SysMyPermissionService permissionService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {SysMyUser user userService.getUserInfoByUserId(username);// 如果用户不存在if (user null){throw new UsernameNotFoundException(用户名或者密码错误);}// 根据用户id查询用户权限ListSysMyPermission permissionList permissionService.getPermissionListByUserId(user.getSid());// 取出权限中配置codeListString collect permissionList.stream().filter(item - item ! null).map(item - item.getPermissionCode()).filter(item - item ! null).collect(Collectors.toList());// 转为数据String[] strings collect.toArray(new String[collect.size()]);ListGrantedAuthority authorityList AuthorityUtils.createAuthorityList(strings);// 配置权限user.setAuthorities(authorityList);// 配置菜单user.setPermissionList(permissionList);// 授权return user;} }4.5.自定义异常 自定义异常通过传入的异常 可以获取对应的信息返回给前端 4.5.1.Token认证自定义异常 /*** 自定义异常 * AuthenticationException 是spring security提供的异常* 通过传入的异常 可以获取对应的信息返回给前端* token异常*/ public class TokenException extends AuthenticationException {public TokenException(String msg) {super(msg);} } 4.5.2.用户认证自定义异常 /*** 自定义异常* 通过传入的异常 可以获取对应的信息返回给前端* 用户认证异常*/ public class CustomerAuthenionException extends AuthenticationException {public CustomerAuthenionException(String msg) {super(msg);} }4.6.编写自定义处理器 通过实现SpringSecurity提供的一些接口我们可以更好地管理身份验证和授权流程提高用户体验和应用程序的安全性。 4.6.1.匿名用户访问处理器 AuthenticationEntryPoint 作用AuthenticationEntryPoint 用于处理用户尝试访问受保护资源但未进行身份验证的情况。当用户尝试访问需要身份验证的资源但尚未进行身份验证时AuthenticationEntryPoint 将被调用来触发身份验证流程。详细讲解当用户尝试访问安全受保护的资源但未进行身份验证时AuthenticationEntryPoint 的 commence() 方法将被调用。在这个方法中我们可以定制返回响应给用户例如重定向到登录页面或返回401未授权错误等。 /*** 匿名用户访问资源处理器*/ Component(loginAuthenticationHandler) public class LoginAuthenticationHandler implements AuthenticationEntryPoint {Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {response.setContentType(application/json;charsetUTF-8);ServletOutputStream out response.getOutputStream();String res JSONObject.toJSONString(ResultObject.createInstance(false,600,匿名用户没有权限进行访问));out.write(res.getBytes(UTF-8));out.flush();out.close();} }4.6.2.认证用户无权限处理器 AccessDeniedHandler 作用AccessDeniedHandler 用于处理用户尝试访问受保护资源但权限不足的情况。当用户虽然进行了身份验证但由于缺乏足够的权限而被拒绝访问资源时AccessDeniedHandler 将被调用。详细讲解AccessDeniedHandler 的 handle() 方法在访问被拒绝时被调用。我们可以在这个方法中定义自定义的行为例如返回自定义的错误页面、向用户发送通知或记录拒绝的访问尝试。 /*** 认证用户访问无权限处理器*/ Component(loginAccessDefineHandler) public class LoginAccessDefineHandler implements AccessDeniedHandler {Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {response.setContentType(application/json;charsetUTF-8);ServletOutputStream out response.getOutputStream();String res JSONObject.toJSONString(ResultObject.createInstance(false,700,您没有开通对应的权限请联系管理员));out.write(res.getBytes(UTF-8));out.flush();out.close();} } 4.6.3.账户信息异常处理器 AuthenticationFailureHandler 作用AuthenticationFailureHandler 用于处理身份验证失败的情况。当用户提供的凭据无效或身份验证过程出现错误时AuthenticationFailureHandler 将被调用。详细讲解AuthenticationFailureHandler 的 onAuthenticationFailure() 方法在身份验证失败时被调用。我们可以在这个方法中执行自定义的行为例如记录登录失败次数、向用户发送通知或返回自定义的错误页面。 Component(loginFiledHandler) public class LoginFiledHandler implements AuthenticationFailureHandler {Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {//1.设置响应编码response.setContentType(application/json;charsetUTF-8);ServletOutputStream out response.getOutputStream();String str null;int code 500;if(exception instanceof AccountExpiredException){str 账户过期登录失败!;}else if(exception instanceof BadCredentialsException){str 用户名或密码错误登录失败!;}else if(exception instanceof CredentialsExpiredException){str 密码过期登录失败!;}else if(exception instanceof DisabledException){str 账户被禁用登录失败!;}else if(exception instanceof LockedException){str 账户被锁登录失败!;}else if(exception instanceof InternalAuthenticationServiceException){str 账户不存在登录失败!;}else if(exception instanceof CustomerAuthenionException){//token验证失败code 600;str exception.getMessage();} else{str 登录失败!;}// 设置返回格式String res JSONObject.toJSONString(ResultObject.createInstance(false,str));out.write(res.getBytes(UTF-8));out.flush();out.close();} } 4.6.4.登录成功处理器 AuthenticationSuccessHandler 作用AuthenticationSuccessHandler 用于处理身份验证成功的情况。当用户成功进行身份验证并被授权访问资源时AuthenticationSuccessHandler 将被调用。详细讲解AuthenticationSuccessHandler 的 onAuthenticationSuccess() 方法在身份验证成功时被调用。我们可以在这个方法中执行自定义的行为例如记录登录成功的日志、向用户发送欢迎消息或重定向到特定页面。 /*** 自定义认证成功处理器*/ Component(loginSuccessHandler) public class LoginSuccessHandler implements AuthenticationSuccessHandler {Resourceprivate RedisCache redisCache;Overridepublic void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {SysMyUser user (SysMyUser)authentication.getPrincipal();// 登录成功处理//1.生成tokenString token TokenUtil.genAccessToken(user.getUsername());long expireTime TokenUtil.getExpirationTime(token);// 配置一下返回给前端的token信息LoginResultObject vo new LoginResultObject();// 将实体类信息转为JSON// TODO 将token存入coookie中 后面加载页面 根据用户的id取查询对应的权限vo.setUserInfo(user);vo.setCode(200L);// TODO 将token存放到redis中 退出或者修改密码 清空token 获取的时候 也从redis中进行获取redisCache.setCacheObject(httpServletRequest.getRemoteAddr(),token,TokenUtil.ACCESS_EXPIRE, TimeUnit.MILLISECONDS);vo.setToken(token);vo.setExpireTime(expireTime);String res JSONObject.toJSONString(vo);httpServletResponse.setContentType(application/json;charsetUTF-8);ServletOutputStream out httpServletResponse.getOutputStream();out.write(res.getBytes(UTF-8));out.flush();out.close();} } 4.7.自定义过滤器 实现 Spring Security 中的 OncePerRequestFilter 接口用于处理用户请求的过滤逻辑。 该过滤器用于对用户的请求进行拦截验证用户的访问权限和身份信息。如果请求的 URL 是某些特定的资源或者登录页面则直接放行。如果不是登录请求则对请求中的 token 进行验证以确保用户的身份信息有效。如果验证通过则将用户的身份信息设置到 Spring Security 的上下文中从而完成用户的身份认证。 Component(checkTokenFilter)将该类声明为 Spring 组件并指定其名称为 “checkTokenFilter”。 EqualsAndHashCode(callSuperfalse)生成 equals() 和 hashCode() 方法忽略父类 OncePerRequestFilter。 DataLombok 注解自动生成 getter、setter、equals、hashCode 等方法。 Autowired 和 Value用于依赖注入和获取配置信息。 doFilterInternal方法这是 OncePerRequestFilter 类的抽象方法用于实现具体的请求过滤逻辑。 首先判断请求的 URL 是否属于特定的资源如果是则放行。判断是否是登录请求如果是则直接放行。如果不是登录请求则验证请求中的 token确保用户的身份信息有效。如果 token 验证失败则调用 AuthenticationFailureHandler 处理身份验证失败的情况。如果 token 验证通过则将用户的身份信息设置到 Spring Security 的上下文中。 validateToken方法用于验证请求中的 token。 首先从请求头部获取 token如果没有则从请求参数中获取如果仍然没有则从 Redis 缓存中获取。解析 token获取其中的用户名。根据用户名加载用户信息使用自定义的 CustomerUserDetailsService。如果用户信息加载成功则创建 UsernamePasswordAuthenticationToken并将用户信息设置到 Spring Security 上下文中。 最后调用 filterChain.doFilter(httpServletRequest, httpServletResponse)将请求传递给下一个过滤器处理。 Data Component(checkTokenFilter) EqualsAndHashCode(callSuperfalse) public class CheckTokenFilter extends OncePerRequestFilter {Value(${hrfan.login.url})private String loginUrl;Autowiredprivate LoginFiledHandler loginFailureHandler;Autowiredprivate CustomerUserDetailsService customerUserDetailsService;Resourceprivate RedisCache redisCache;Overrideprotected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {//获取请求的url(读取配置文件的url)String url httpServletRequest.getRequestURI();if (StringUtils.contains(httpServletRequest.getServletPath(), swagger)|| StringUtils.contains(httpServletRequest.getServletPath(), webjars)|| StringUtils.contains(httpServletRequest.getServletPath(), v3)|| StringUtils.contains(httpServletRequest.getServletPath(), profile)|| StringUtils.contains(httpServletRequest.getServletPath(), swagger-ui)|| StringUtils.contains(httpServletRequest.getServletPath(), swagger-resources)|| StringUtils.contains(httpServletRequest.getServletPath(), csrf)|| StringUtils.contains(httpServletRequest.getServletPath(), favicon)|| StringUtils.contains(httpServletRequest.getServletPath(), v2)|| StringUtils.contains(httpServletRequest.getServletPath(), user)|| StringUtils.contains(httpServletRequest.getServletPath(), getImageCode)) {filterChain.doFilter(httpServletRequest, httpServletResponse);}else if (StringUtils.equals(url,loginUrl)){// 是登录请求放行filterChain.doFilter(httpServletRequest, httpServletResponse);}else {try {//token验证如果不是登录请求 验证toeknif(!url.equals(loginUrl)){validateToken(httpServletRequest);}}catch (AuthenticationException e){loginFailureHandler.onAuthenticationFailure(httpServletRequest,httpServletResponse,e);return;}filterChain.doFilter(httpServletRequest,httpServletResponse);}}//token验证private void validateToken(HttpServletRequest request){//从请求的头部获取tokenString token request.getHeader(token);//如果请求头部没有获取到token则从请求参数中获取tokenif(StringUtils.isEmpty(token)){token request.getParameter(token);}if (StringUtils.isEmpty(token)){// 请求参数中也没有 那就从redis中进行获取根据ip地址取token redisCache.getCacheObject(request.getRemoteAddr());}if(StringUtils.isEmpty(token)){throw new CustomerAuthenionException(token不存在);}//解析tokenString username TokenUtil.getUserFromToken(token);if(StringUtils.isEmpty(username)){throw new CustomerAuthenionException(token解析失败!);}//获取用户信息UserDetails user customerUserDetailsService.loadUserByUsername(username);if(user null){throw new CustomerAuthenionException(token验证失败!);}UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(user,null,user.getAuthorities());authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));//设置到spring security上下文SecurityContextHolder.getContext().setAuthentication(authenticationToken);} }4.8.设置登录返回信息 用户返回用户登录 成功或者失败的信息成功后需要包含用户的相关信息 和token /*** 登录返回信息*/ Data public class LoginResultObject {private String token;//token过期时间private Long expireTime;private SysMyUser userInfo;private Long code; }4.9.编写SpringSecurity配置 #### 注意因为新版本的SpringSecurity和旧版本的差距较大所以这里保留了旧版本的写法我使用的SpringBoot 和 SpringSecurity 版本都是相对较新的 3.1.8版本 JDK版本是21import com.sys.my.config.security.details_service.CustomerUserDetailsService; import com.sys.my.config.security.filter.CheckTokenFilter; import com.sys.my.config.security.handler.LoginAccessDefineHandler; import com.sys.my.config.security.handler.LoginAuthenticationHandler; import com.sys.my.config.security.handler.LoginFiledHandler; import com.sys.my.config.security.handler.LoginSuccessHandler; import jakarta.annotation.Resource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;import java.util.Collections;/*** SpringSecurity配置类*/ Configuration EnableWebSecurity //启用Spring Security public class SpringSecurityConfig {Resourceprivate CustomerUserDetailsService customerUserDetailsService;Resourceprivate LoginSuccessHandler loginSuccessHandler;Resourceprivate LoginFiledHandler loginFiledHandler;Resourceprivate LoginAuthenticationHandler loginAuthenticationHandler;Resourceprivate LoginAccessDefineHandler loginAccessDefineHandler;Resourceprivate CheckTokenFilter checkTokenFilter;/*** 密码处理* return*/Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}/*** 新版的实现方法不再和旧版一样在配置类里面重写方法而是构建了一个过滤链对象并通过Bean注解注入到IOC容器中* 新版整体代码 注意新版AuthenticationManager认证管理器默认全局* param http http安全配置* return SecurityFilterChain* throws Exception 异常*/Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http // 使用自己自定义的过滤器 去过滤接口请求.addFilterBefore(checkTokenFilter, UsernamePasswordAuthenticationFilter.class).formLogin((formLogin) -// 这里更改SpringSecurity的认证接口地址这样就默认处理这个接口的登录请求了formLogin.loginProcessingUrl(/api/v1/user/login)// 自定义的登录验证成功或失败后的去向.successHandler(loginSuccessHandler).failureHandler(loginFiledHandler))// 禁用了 CSRF 保护。.csrf((csrf) - csrf.disable())// 配置了会话管理策略为 STATELESS无状态。在无状态的会话管理策略下应用程序不会创建或使用 HTTP 会话每个请求都是独立的服务器不会在请求之间保留任何状态信息。.sessionManagement((sessionManagement) - sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)).authorizeRequests((authorizeRequests) -// 这里过滤一些 不需要token的接口地址authorizeRequests.requestMatchers(/api/v1/test/getTestInfo).permitAll().requestMatchers( /v3/**,/profile/**,/swagger-ui.html,/swagger-resources/**,/v2/api-docs,/v3/api-docs,/webjars/**,/swagger-ui/**,/v2/**,/favicon.ico,/webjars/springfox-swagger-ui/**,/static/**, /webjars/**, /v2/api-docs, /v2/feign-docs,/swagger-resources/configuration/ui,/test/user,/swagger-resources, /swagger-resources/configuration/security,/swagger-ui.html, /webjars/**).permitAll().requestMatchers(/api/v1/user/login,/api/v1/user/getImageCode).permitAll().anyRequest().authenticated()).exceptionHandling((exceptionHandling) - exceptionHandling.authenticationEntryPoint(loginAuthenticationHandler) // 匿名处理.accessDeniedHandler(loginAccessDefineHandler) // 无权限处理).cors((cors) - cors.configurationSource(configurationSource())).headers((headers) - headers.frameOptions((frameOptionsConfig - frameOptionsConfig.disable()))).headers((headers) - headers.frameOptions((frameOptionsConfig - frameOptionsConfig.sameOrigin())));// 构建过滤链并返回return http.build();}// 旧版本 需要继承 extends WebSecurityConfigurerAdapter// 新版的比较简单直接定义好数据源注入就可以了无需手动到配置类中去将它提交给AuthenticationManager进行管理。// /**// * 配置认证处理器// * 自定义的UserDetailsService// * param auth// * throws Exception// */// Override// protected void configure(AuthenticationManagerBuilder auth) throws Exception {// auth.userDetailsService(customerUserDetailsService);// }// /**// * 配置权限资源// * param http// * throws Exception// */// Override// protected void configure(HttpSecurity http) throws Exception {// // 每次请求前检查token// http.addFilterBefore(checkTokenFilter, UsernamePasswordAuthenticationFilter.class);// http.formLogin()// .loginProcessingUrl(/api/v1/user/login)// // 自定义的登录验证成功或失败后的去向// .successHandler(loginSuccessHandler).failureHandler(loginFiledHandler)// // 禁用csrf防御机制(跨域请求伪造)这么做在测试和开发会比较方便。// .and().csrf().disable()// .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)// .and()// .authorizeRequests()// .antMatchers(/api/v1/test/getTestInfo).permitAll()// // 放心swagger相关请求// .antMatchers( /v3/**,/profile/**,/swagger-ui.html,// /swagger-resources/**,// /v2/api-docs,// /v3/api-docs,// /webjars/**,/swagger-ui/**,/v2/**,/favicon.ico,/webjars/springfox-swagger-ui/**,/static/**, /webjars/**, /v2/api-docs, /v2/feign-docs,// /swagger-resources/configuration/ui,// /swagger-resources, /swagger-resources/configuration/security,// /swagger-ui.html, /webjars/**).permitAll()// .antMatchers(/api/v1/user/login,/api/v1/user/getImageCode).permitAll()// .anyRequest().authenticated()// .and()// .exceptionHandling()// // 匿名处理// .authenticationEntryPoint(loginAuthenticationHandler)// // 无权限处理// .accessDeniedHandler(loginAccessDefineHandler)// // 跨域配置// .and()// .cors()// .configurationSource(configurationSource());// // 设置iframe// http.headers().frameOptions().sameOrigin();// http.headers().frameOptions().disable();//// }/*** 跨域配置*/CorsConfigurationSource configurationSource() {CorsConfiguration corsConfiguration new CorsConfiguration();corsConfiguration.setAllowedHeaders(Collections.singletonList(*));corsConfiguration.setAllowedMethods(Collections.singletonList(*));corsConfiguration.setAllowedOrigins(Collections.singletonList(*));corsConfiguration.setMaxAge(3600L);UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration(/**, corsConfiguration);return source;} } 4.10.配置文件配置 hrfan:login:url: /api/v1/user/login5.测试 5.1.测试登录密码错误 5.2.测试正确密码 5.3.测试无token访问接口 SpringSecurity为我们提供了基于注解的权限控制方案。 在启动类上加上 EnableGlobalMethodSecurity(prePostEnabled true) GetMapping(/jjwt)PreAuthorize(hasAuthority(user_list))public MapString, String jjwt(){// 这里的user_list 就是我们权限中permission_codethrow new RuntimeException(测试无token访问);}5.4.测试不登陆访问 5.5.测试登录访问不受限制接口 5.6.测试放开的通用接口 例如/** 5.7.测试权限标识 和数据库不一致
http://www.pierceye.com/news/137794/

相关文章:

  • 烟台建网站公司哪家好辽源做网站的公司
  • 建设企业网站地址网站空间 虚拟主机
  • h5网站模板免费下载网页源码提取工具
  • 网站设计和网页设计建网站必备软件
  • 中国建设银行上海市分行网站音乐网站开发可行性分析
  • 如何用天地图做网站做面包有哪些网站知乎
  • 买了域名之后怎么建设网站做网站一年赚一千万
  • 跟网站开发公司签合同主要要点个人网站logo需要备案吗
  • 免费询盘网站自我介绍ppt模板
  • 中国会议营销网站怎么做找优惠券的网站
  • 做网站的那些事wordpress改写
  • 仿造整个网站呼市网站建设公司
  • 网站被黑客入侵怎么办企业文化墙设计网站推荐
  • 建设网站的群婚礼婚庆网站建设需求分析
  • 全椒县城乡建设局网站网站怎么做营销策划
  • 响应式网站制作流程河北企业建网站
  • 常州新北区有做淘宝网站策划的吗什么建设网站
  • 成品网站源码68w68游戏wordpress php推送示例
  • 博优云软件官方网站wordpress 个人
  • 登封 网站建设烟台网站关键词推广
  • 深圳实惠的专业建站公司淘宝券商城网站制作
  • 珠海手机网站建设成都设计网站
  • 网站mp3播放器代码国家企业信息系统官方
  • 江西建设银行招聘网站pc网站还有必要做吗
  • 网站建设几个要素做网站需要学会什么软件
  • 做视频网站什么平台好站酷设计网站首页
  • 班级网站设计论文网站多国语言
  • 网站制作评价标准网站服务器怎么收费
  • 怎么建立自己的网站平台多少钱wordpress自建菜单
  • 深圳购物网站如何制作外贸网站 wordpress