微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(3)
你在学习数据库相关的知识吗?本文《微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(3)》,主要介绍的内容就涉及到MySQL、Redis、Java、spring、springboot,如果你想提升自己的开发能力,就不要错过这篇文章,大家要知道编程理论基础和实战操作都是不可或缺的哦!
认证中心

pom.xml
zuul-auth com.babaznkj.com 1.0-SNAPSHOT 4.0.0 auth-center 8 8 com.babaznkj.com common mysql mysql-connector-java ${mysql.version} org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis.starter.version} com.alibaba druid-spring-boot-starter ${druid.starter.version}
yml
server:
port: 8090
baba:
security:
jwt:
secret: otherpeopledontknowit
url: /auth
header: Authorization
prefix: Bearer
expiration: 86400
language: CN
spring:
application:
name: auth
datasource:
name: test
url: jdbc:mysql://localhost:3306/baba_icloud_test1?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: carry0610A
# druid 连接池
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
main:
allow-bean-definition-overriding: true # 这个表示允许我们覆盖OAuth2放在容器中的bean对象,一定要配置
redis:
host: 192.168.3.119
port: 6379
password: 123456
ribbon:
ReadTimeout: 5000
SocketTimeout: 5000
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
instance:
prefer-ip-address: false
management:
endpoints:
security:
enabled: false
web:
exposure:
include: "*"
mybatis:
mapper-locations: classpath:mapper/*.xml # mapper映射文件位置
type-aliases-package: shuaicj.example.security.common.entity # 实体类所在的位置
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
SecurityConfig.java : 这里过滤器可以返回自定义异常。
package com.baba.security.auth.config; import com.baba.security.auth.filter.JwtUsernamePasswordAuthenticationFilter; import com.baba.security.auth.service.impl.MemberUserDetailsService; import com.baba.security.common.config.JwtProperties; import com.baba.security.common.exception.JWTAuthenticationEntryPoint; import com.baba.security.common.handler.SimpleAccessDeniedHandler; import com.baba.security.common.handler.SimpleAuthenticationEntryPoint; import com.baba.security.common.utils.MD5Util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.servlet.http.HttpServletResponse; /** * Config login authentication. * * @author shuaicj 2017/10/18 */ @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MemberUserDetailsService memberUserDetailsService; @Autowired private JwtProperties jwtProperties; @Bean public JwtProperties jwtConfig() { return new JwtProperties(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(memberUserDetailsService).passwordEncoder(new PasswordEncoder() { /** * 对密码MD5 * @param rawPassword * @return */ @Override public String encode(CharSequence rawPassword) { return MD5Util.encode((String) rawPassword); } /** * rawPassword 用户输入的密码 * encodedPassword 数据库DB的密码 * @param rawPassword * @param encodedPassword * @return */ @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { String rawPass = MD5Util.encode((String) rawPassword); boolean result = rawPass.equals(encodedPassword); return result; } }); } @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity .cors(). and() .csrf().disable() .logout().disable() // .formLogin().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .exceptionHandling().authenticationEntryPoint( (req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED)) .and() // .addFilterBefore(new WebSecurityCorsFilter(), ChannelProcessingFilter.class) // 保证跨域的过滤器首先触发 .addFilterAfter(new JwtUsernamePasswordAuthenticationFilter(jwtProperties, authenticationManager()), UsernamePasswordAuthenticationFilter.class) .authorizeRequests() .antMatchers(HttpMethod.OPTIONS).permitAll() .antMatchers(jwtProperties.getUrl()).permitAll() .anyRequest().authenticated() // // 加一句这个 .and() .exceptionHandling().authenticationEntryPoint(new JWTAuthenticationEntryPoint()) .accessDeniedHandler(new SimpleAccessDeniedHandler()).authenticationEntryPoint(new SimpleAuthenticationEntryPoint()); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }PermissionMapper.java
package com.baba.security.auth.dao; import com.baba.security.auth.entity.Permission; import com.baba.security.auth.entity.PermissionEntity; import java.util.List; public interface PermissionMapper { /** * delete by primary key * * @param id primaryKey * @return deleteCount */ int deleteByPrimaryKey(Long id); /** * insert record to table * * @param record the record * @return insert count */ int insert(Permission record); /** * insert record to table selective * * @param record the record * @return insert count */ int insertSelective(Permission record); /** * select by primary key * * @param id primary key * @return object by primary key */ Permission selectByPrimaryKey(Long id); /** * update record selective * * @param record the updated record * @return update count */ int updateByPrimaryKeySelective(Permission record); /** * update record * * @param record the updated record * @return update count */ int updateByPrimaryKey(Permission record); ListfindByAll(Permission permission); List findPermissionEntity(Permission permission); List findPermissionByUsername(String username); } RoleMapper.java
package com.baba.security.auth.dao; import com.baba.security.auth.entity.Role; import java.util.List; public interface RoleMapper { /** * delete by primary key * @param id primaryKey * @return deleteCount */ int deleteByPrimaryKey(Integer id); /** * insert record to table * @param record the record * @return insert count */ int insert(Role record); /** * insert record to table selective * @param record the record * @return insert count */ int insertSelective(Role record); /** * select by primary key * @param id primary key * @return object by primary key */ Role selectByPrimaryKey(Integer id); /** * update record selective * @param record the updated record * @return update count */ int updateByPrimaryKeySelective(Role record); /** * update record * @param record the updated record * @return update count */ int updateByPrimaryKey(Role record); ListfindByAll(Role role); } RolePermissionMapper.java
package com.baba.security.auth.dao; import com.baba.security.auth.entity.RolePermission; import java.util.List; public interface RolePermissionMapper { /** * insert record to table * @param record the record * @return insert count */ int insert(RolePermission record); /** * insert record to table selective * @param record the record * @return insert count */ int insertSelective(RolePermission record); ListfindByAll(RolePermission rolePermission); } UserMapper.java
package com.baba.security.auth.dao; import com.baba.security.auth.entity.User; import java.util.List; public interface UserMapper { /** * delete by primary key * * @param id primaryKey * @return deleteCount */ int deleteByPrimaryKey(Long id); /** * insert record to table * * @param record the record * @return insert count */ int insert(User record); /** * insert record to table selective * * @param record the record * @return insert count */ int insertSelective(User record); /** * select by primary key * * @param id primary key * @return object by primary key */ User selectByPrimaryKey(Long id); User findByUsername(String username); /** * update record selective * * @param record the updated record * @return update count */ int updateByPrimaryKeySelective(User record); /** * update record * * @param record the updated record * @return update count */ int updateByPrimaryKey(User record); ListfindByAll(User user); } Permission.java
package com.baba.security.auth.entity; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; import java.util.Date; @Getter @Setter @ToString public class Permission implements Serializable { /** * 主鍵id */ private Long id; /** * 父级权限id */ private Long pid; /** * 中文导航栏名称 */ private String name; /** * 英文导航栏名称 */ private String eName; /** * 权限标记 */ private String tag; /** * 权限值 */ private String value; /** * 图标 */ private String icon; /** * 权限类型:0->目录;1->菜单;2->按钮(接口绑定权限) */ private Integer type; /** * 请求url */ private String url; /** * 启用状态;0 正常 1删除 */ private Integer status; /** * 排序 */ private Integer sort; /** * 创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 创建人 */ private String createdBy; /** * 修改人 */ private String updatedBy; private static final long serialVersionUID = 1L; }PermissionEntity.java
package com.baba.security.auth.entity; import lombok.Data; @Data public class PermissionEntity { private Integer id; // 权限名称 private String permName; // 权限标识 private String permTag; // 请求url private String url; }Role.java
package com.baba.security.auth.entity; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; import java.util.Date; @Getter @Setter @ToString public class Role implements Serializable { private Integer id; /** * 用户id */ private Long userId; /** * 角色名称 */ private String roleName; /** * 角色描述 */ private String roleDesc; /** * 创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 创建人 */ private String createdBy; /** * 修改人 */ private String updatedBy; private static final long serialVersionUID = 1L; }RolePermission.java
package com.baba.security.auth.entity; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; @Getter @Setter @ToString public class RolePermission implements Serializable { private Integer roleId; private Integer permId; private static final long serialVersionUID = 1L; }User: 实现UserDetails
package com.baba.security.auth.entity; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; @Getter @Setter @ToString public class User implements UserDetails, Serializable { /** * 主键id */ private Long id; /** * 子用户ID */ private Long pid; /** * 租户id */ private Long tenantId; /** * 名称 */ private String username; /** * 密码 */ private String password; /** * 昵称 */ private String nick; /** * 性别(男/女) */ private int gender; /** * 年龄 */ private Integer age; /** * 头像地址 */ private String headImg; /** * 电话号码 */ private String phone; /** * 0:禁用/1:启用 */ private Integer state; /** * 友盟推送认证token */ private String pushToken; /** * app端盐值 */ private String appSalt; /** * web端盐值 */ private String webSalt; /** * 当前账户是否可用 */ private boolean enabled= true; /** * 当前账户是否过期 */ private boolean accountNonExpired = true; /** * 当前账户是否锁定 */ private boolean accountNonLocked= true; /** * 当前账户凭证是否过期 */ private boolean credentialsNonExpired= true; /** * 创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 创建人 */ private String createBy; /** * 修改人 */ private String updateBy; /** * 秘钥 */ private String secretKey; private static final long serialVersionUID = 1L; /** * 权限列表 */ private Listauthorities = new ArrayList (); public Collection extends GrantedAuthority> getAuthorities() { return authorities; } public void setAuthorities(List authorities) { this.authorities = authorities; } } JwtUsernamePasswordAuthenticationFilter.java :这里也要放行【
config.getUrl()
】登录接口,成功和失败的方法调用。token的生成,动态颜值处理。package com.baba.security.auth.filter; import com.baba.security.auth.dao.UserMapper; import com.baba.security.auth.entity.User; import com.baba.security.common.config.JwtProperties; import com.baba.security.common.constant.RedisConstant; import com.baba.security.common.enums.ResultCode; import com.baba.security.common.exception.DefinitException; import com.baba.security.common.utils.JwtUtils; import com.baba.security.common.utils.RedisUtils; import com.baba.security.common.utils.SaltUtils; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang.StringUtils; import org.springframework.context.ApplicationContext; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.InternalAuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.servlet.HandlerExceptionResolver; import javax.servlet.FilterChain; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.concurrent.TimeUnit; /** * Authenticate the request to url /login by POST with json body '{ username, password }'. * If successful, response the client with header 'Authorization: Bearer jwt-token'. * * @author shuaicj 2017/10/18 */ public class JwtUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { // private final JwtAuthenticationConfig config; private final JwtProperties config; private final ObjectMapper mapper; public JwtUsernamePasswordAuthenticationFilter(JwtProperties config, AuthenticationManager authManager) { super(new AntPathRequestMatcher(config.getUrl(), "POST")); setAuthenticationManager(authManager); this.config = config; this.mapper = new ObjectMapper(); } // 接收并解析用户凭证 @Override public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse rsp) throws AuthenticationException, IOException { try { User user = mapper.readValue(req.getInputStream(), User.class); return getAuthenticationManager().authenticate( new UsernamePasswordAuthenticationToken( user.getUsername(), user.getPassword(), Collections.emptyList() ) ); } catch (InternalAuthenticationServiceException e) { ServletContext context = req.getServletContext(); ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); HandlerExceptionResolver resolver = ctx.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); resolver.resolveException(req, rsp, null, new DefinitException(ResultCode.USER_NOT_FOUND)); return null; // throw new DefinitException(ResultCode.USER_NOT_FOUND); } } // 用户成功登录后,这个方法会被调用,我们在这个方法里生成token @Override protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse rsp, FilterChain chain, Authentication auth) throws IOException { User user = (User) auth.getPrincipal(); // filter过滤器使用Autowired注入Bean为null ServletContext context = req.getServletContext(); ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); RedisUtils redisUtil = ctx.getBean(RedisUtils.class); UserMapper userMapper = ctx.getBean(UserMapper.class); User updateSalt = new User(); updateSalt.setId(user.getId()); //1.生成随机盐 String salt = SaltUtils.getSalt(8); String userAgent = req.getHeader("user-agent").toLowerCase(); String language = req.getHeader("language"); if (userAgent.indexOf("micromessenger") != -1) { //微信 } else if (userAgent.indexOf("android") != -1 || userAgent.indexOf("iphone") != -1 || userAgent.indexOf("ipad") != -1 || userAgent.indexOf("ipod") != -1) { //安卓 或者 苹果 //2.将随机盐保存到Redis redisUtil.setEx(RedisConstant.PREFIX_APP + user.getId(), salt, 1, TimeUnit.DAYS); updateSalt.setAppSalt(salt); } else { //电脑 //2.将随机盐保存到Redis redisUtil.setEx(RedisConstant.PREFIX_WEB + user.getId(), salt, 1, TimeUnit.DAYS); updateSalt.setWebSalt(salt); } //3.更新Mysql随机盐值 userMapper.updateByPrimaryKeySelective(updateSalt); user.setSecretKey(salt); if (StringUtils.isEmpty(language)) { language = config.getLanguage(); } String token = JwtUtils.generateJsonWebToken(auth, salt, language); redisUtil.setEx(token, user.getId().toString(), 2, TimeUnit.HOURS); rsp.addHeader(config.getHeader(), config.getPrefix() + " " + token); HashMapmap = new HashMap(2); map.put("code", ResultCode.USER_AUTH_SUCCESS.getCode()); map.put("msg", ResultCode.USER_AUTH_SUCCESS.getMessage()); rsp.setStatus(HttpServletResponse.SC_OK); rsp.setCharacterEncoding("utf-8"); rsp.setContentType(MediaType.APPLICATION_JSON_VALUE); rsp.getWriter().write(new ObjectMapper().writeValueAsString(map)); } @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { // response.getWriter().write("authentication failed, reason: " + failed.getMessage()); System.out.println(failed.getMessage()); ServletContext context = request.getServletContext(); ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); HandlerExceptionResolver resolver = ctx.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); resolver.resolveException(request, response, null, new DefinitException(ResultCode.LOGIN_METHOD_WROND)); } } MemberUserDetailsService.java : 查询的tag必须拼接前缀
"ROLE_"
,而不能在数据库中添加。package com.baba.security.auth.service.impl; import com.baba.security.auth.entity.PermissionEntity; import com.baba.security.auth.entity.User; import com.baba.security.auth.service.PermissionService; import com.baba.security.auth.service.UserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; /** * @ClassName MemberUserDetailsService * @Author wulongbo * @Version V1.0 **/ @Component @Slf4j public class MemberUserDetailsService implements UserDetailsService { @Autowired private UserService userService; @Autowired private PermissionService permissionService; /** * loadUserByUserName * * @param username * @return * @throws UsernameNotFoundException */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 1.根据该用户名称查询在数据库中是否存在 User userEntity = userService.findByUsername(username); if (userEntity == null) { return null; } // 2.查询对应的用户权限 ListlistPermission = permissionService.findPermissionByUsername(username); List authorities = new ArrayList (); listPermission.forEach(user -> { authorities.add(new SimpleGrantedAuthority("ROLE_" + user.getPermTag())); }); // 3.将该权限添加到security userEntity.setAuthorities(authorities); return userEntity; } } PermissionServiceImpl.java
package com.baba.security.auth.service.impl; import com.baba.security.auth.dao.PermissionMapper; import com.baba.security.auth.entity.Permission; import com.baba.security.auth.entity.PermissionEntity; import com.baba.security.auth.service.PermissionService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class PermissionServiceImpl implements PermissionService { @Resource private PermissionMapper permissionMapper; @Override public int deleteByPrimaryKey(Long id) { return permissionMapper.deleteByPrimaryKey(id); } @Override public int insert(Permission record) { return permissionMapper.insert(record); } @Override public int insertSelective(Permission record) { return permissionMapper.insertSelective(record); } @Override public Permission selectByPrimaryKey(Long id) { return permissionMapper.selectByPrimaryKey(id); } @Override public int updateByPrimaryKeySelective(Permission record) { return permissionMapper.updateByPrimaryKeySelective(record); } @Override public int updateByPrimaryKey(Permission record) { return permissionMapper.updateByPrimaryKey(record); } @Override public ListfindByAll(Permission permission) { return permissionMapper.findByAll(permission); } @Override public List findPermissionEntity(Permission permission) { return permissionMapper.findPermissionEntity(permission); } @Override public List findPermissionByUsername(String username) { return permissionMapper.findPermissionByUsername(username); } }
UserServiceImpl.java
package com.baba.security.auth.service.impl; import com.baba.security.auth.dao.UserMapper; import com.baba.security.auth.entity.User; import com.baba.security.auth.service.UserService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class UserServiceImpl implements UserService { @Resource private UserMapper userMapper; @Override public int deleteByPrimaryKey(Long id) { return userMapper.deleteByPrimaryKey(id); } @Override public int insert(User record) { return userMapper.insert(record); } @Override public int insertSelective(User record) { return userMapper.insertSelective(record); } @Override public User selectByPrimaryKey(Long id) { return userMapper.selectByPrimaryKey(id); } @Override public int updateByPrimaryKeySelective(User record) { return userMapper.updateByPrimaryKeySelective(record); } @Override public int updateByPrimaryKey(User record) { return userMapper.updateByPrimaryKey(record); } @Override public ListfindByAll(User user) { return userMapper.findByAll(user); } @Override public User findByUsername(String username) { return userMapper.findByUsername(username); } }
PermissionService.java
package com.baba.security.auth.service; import com.baba.security.auth.entity.Permission; import com.baba.security.auth.entity.PermissionEntity; import java.util.List; public interface PermissionService { int deleteByPrimaryKey(Long id); int insert(Permission record); int insertSelective(Permission record); Permission selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(Permission record); int updateByPrimaryKey(Permission record); ListfindByAll(Permission permission); List findPermissionEntity(Permission permission); List findPermissionByUsername(String username); } UserService.java
package com.baba.security.auth.service; import com.baba.security.auth.entity.User; import java.util.List; public interface UserService { int deleteByPrimaryKey(Long id); int insert(User record); int insertSelective(User record); User selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(User record); int updateByPrimaryKey(User record); ListfindByAll(User user); User findByUsername(String username); } PermissionMapper.xml
id, pid, `name`, e_name, tag, `value`, icon, `type`, url, `status`, sort, create_time, update_time, created_by, updated_by delete from tbl_permission where id = #{id,jdbcType=BIGINT} insert into tbl_permission (pid, `name`, e_name, tag, `value`, icon, `type`, url, `status`, sort, create_time, update_time, created_by, updated_by) values (#{pid,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{eName,jdbcType=VARCHAR}, #{tag,jdbcType=VARCHAR}, #{value,jdbcType=VARCHAR}, #{icon,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{url,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, #{sort,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP}, #{createdBy,jdbcType=VARCHAR}, #{updatedBy,jdbcType=VARCHAR}) insert into tbl_permission pid, `name`, e_name, tag, `value`, icon, `type`, url, `status`, sort, create_time, update_time, created_by, updated_by, #{pid,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{eName,jdbcType=VARCHAR}, #{tag,jdbcType=VARCHAR}, #{value,jdbcType=VARCHAR}, #{icon,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{url,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, #{sort,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP}, #{createdBy,jdbcType=VARCHAR}, #{updatedBy,jdbcType=VARCHAR}, update tbl_permission where id = #{id,jdbcType=BIGINT}pid = #{pid,jdbcType=BIGINT}, `name` = #{name,jdbcType=VARCHAR}, e_name = #{eName,jdbcType=VARCHAR}, tag = #{tag,jdbcType=VARCHAR}, `value` = #{value,jdbcType=VARCHAR}, icon = #{icon,jdbcType=VARCHAR}, `type` = #{type,jdbcType=INTEGER}, url = #{url,jdbcType=VARCHAR}, `status` = #{status,jdbcType=INTEGER}, sort = #{sort,jdbcType=INTEGER}, create_time = #{createTime,jdbcType=TIMESTAMP}, update_time = #{updateTime,jdbcType=TIMESTAMP}, created_by = #{createdBy,jdbcType=VARCHAR}, updated_by = #{updatedBy,jdbcType=VARCHAR}, update tbl_permission set pid = #{pid,jdbcType=BIGINT}, `name` = #{name,jdbcType=VARCHAR}, e_name = #{eName,jdbcType=VARCHAR}, tag = #{tag,jdbcType=VARCHAR}, `value` = #{value,jdbcType=VARCHAR}, icon = #{icon,jdbcType=VARCHAR}, `type` = #{type,jdbcType=INTEGER}, url = #{url,jdbcType=VARCHAR}, `status` = #{status,jdbcType=INTEGER}, sort = #{sort,jdbcType=INTEGER}, create_time = #{createTime,jdbcType=TIMESTAMP}, update_time = #{updateTime,jdbcType=TIMESTAMP}, created_by = #{createdBy,jdbcType=VARCHAR}, updated_by = #{updatedBy,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} RoleMapper.xml
id, user_id, role_name, role_desc, create_time, update_time, created_by, updated_by delete from tbl_role where id = #{id,jdbcType=INTEGER} insert into tbl_role (id, user_id, role_name, role_desc, create_time, update_time, created_by, updated_by) values (#{id,jdbcType=INTEGER}, #{userId,jdbcType=BIGINT}, #{roleName,jdbcType=VARCHAR}, #{roleDesc,jdbcType=VARCHAR}, #{createTime,jdbcType=DATE}, #{updateTime,jdbcType=DATE}, #{createdBy,jdbcType=VARCHAR}, #{updatedBy,jdbcType=VARCHAR}) insert into tbl_role id, user_id, role_name, role_desc, create_time, update_time, created_by, updated_by, #{id,jdbcType=INTEGER}, #{userId,jdbcType=BIGINT}, #{roleName,jdbcType=VARCHAR}, #{roleDesc,jdbcType=VARCHAR}, #{createTime,jdbcType=DATE}, #{updateTime,jdbcType=DATE}, #{createdBy,jdbcType=VARCHAR}, #{updatedBy,jdbcType=VARCHAR}, update tbl_role where id = #{id,jdbcType=INTEGER}user_id = #{userId,jdbcType=BIGINT}, role_name = #{roleName,jdbcType=VARCHAR}, role_desc = #{roleDesc,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=DATE}, update_time = #{updateTime,jdbcType=DATE}, created_by = #{createdBy,jdbcType=VARCHAR}, updated_by = #{updatedBy,jdbcType=VARCHAR}, update tbl_role set user_id = #{userId,jdbcType=BIGINT}, role_name = #{roleName,jdbcType=VARCHAR}, role_desc = #{roleDesc,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=DATE}, update_time = #{updateTime,jdbcType=DATE}, created_by = #{createdBy,jdbcType=VARCHAR}, updated_by = #{updatedBy,jdbcType=VARCHAR} where id = #{id,jdbcType=INTEGER} RolePermissionMapper.xml
role_id, perm_id insert into tbl_role_permission (role_id, perm_id) values (#{roleId,jdbcType=INTEGER}, #{permId,jdbcType=INTEGER}) insert into tbl_role_permission role_id, perm_id, #{roleId,jdbcType=INTEGER}, #{permId,jdbcType=INTEGER}, UserMapper.xml
id, pid, tenant_id, username, `password`, nick, gender, age, head_img, phone, `state`, push_token, app_salt, web_salt, enabled, accountNonExpired, accountNonLocked, credentialsNonExpired, create_time, update_time, create_by, update_by delete from tbl_user where id = #{id,jdbcType=BIGINT} insert into tbl_user (pid, tenant_id, username, `password`, nick, gender, age, head_img, phone, `state`, push_token, app_salt, web_salt, enabled, accountNonExpired, accountNonLocked, credentialsNonExpired, create_time, update_time, create_by, update_by) values (#{pid,jdbcType=BIGINT}, #{tenantId,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{nick,jdbcType=VARCHAR}, #{gender,jdbcType=INTEGER}, #{age,jdbcType=INTEGER}, #{headImg,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{state,jdbcType=INTEGER}, #{pushToken,jdbcType=VARCHAR}, #{appSalt,jdbcType=VARCHAR}, #{webSalt,jdbcType=VARCHAR}, #{enabled,jdbcType=BOOLEAN}, #{accountNonExpired,jdbcType=BOOLEAN}, #{accountNonLocked,jdbcType=BOOLEAN}, #{credentialsNonExpired,jdbcType=BOOLEAN}, #{createTime,jdbcType=DATE}, #{updateTime,jdbcType=DATE}, #{createBy,jdbcType=VARCHAR}, #{updateBy,jdbcType=VARCHAR}) insert into tbl_user pid, tenant_id, username, `password`, nick, gender, age, head_img, phone, `state`, push_token, app_salt, web_salt, enabled, accountNonExpired, accountNonLocked, credentialsNonExpired, create_time, update_time, create_by, update_by, #{pid,jdbcType=BIGINT}, #{tenantId,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{nick,jdbcType=VARCHAR}, #{gender,jdbcType=INTEGER}, #{age,jdbcType=INTEGER}, #{headImg,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{state,jdbcType=INTEGER}, #{pushToken,jdbcType=VARCHAR}, #{appSalt,jdbcType=VARCHAR}, #{webSalt,jdbcType=VARCHAR}, #{enabled,jdbcType=BOOLEAN}, #{accountNonExpired,jdbcType=BOOLEAN}, #{accountNonLocked,jdbcType=BOOLEAN}, #{credentialsNonExpired,jdbcType=BOOLEAN}, #{createTime,jdbcType=DATE}, #{updateTime,jdbcType=DATE}, #{createBy,jdbcType=VARCHAR}, #{updateBy,jdbcType=VARCHAR}, update tbl_user where id = #{id,jdbcType=BIGINT}pid = #{pid,jdbcType=BIGINT}, tenant_id = #{tenantId,jdbcType=BIGINT}, username = #{username,jdbcType=VARCHAR}, `password` = #{password,jdbcType=VARCHAR}, nick = #{nick,jdbcType=VARCHAR}, gender = #{gender,jdbcType=INTEGER}, age = #{age,jdbcType=INTEGER}, head_img = #{headImg,jdbcType=VARCHAR}, phone = #{phone,jdbcType=VARCHAR}, `state` = #{state,jdbcType=INTEGER}, push_token = #{pushToken,jdbcType=VARCHAR}, app_salt = #{appSalt,jdbcType=VARCHAR}, web_salt = #{webSalt,jdbcType=VARCHAR}, enabled = #{enabled,jdbcType=BOOLEAN}, accountNonExpired = #{accountNonExpired,jdbcType=BOOLEAN}, accountNonLocked = #{accountNonLocked,jdbcType=BOOLEAN}, credentialsNonExpired = #{credentialsNonExpired,jdbcType=BOOLEAN}, create_time = #{createTime,jdbcType=DATE}, update_time = #{updateTime,jdbcType=DATE}, create_by = #{createBy,jdbcType=VARCHAR}, update_by = #{updateBy,jdbcType=VARCHAR}, update tbl_user set pid = #{pid,jdbcType=BIGINT}, tenant_id = #{tenantId,jdbcType=BIGINT}, username = #{username,jdbcType=VARCHAR}, `password` = #{password,jdbcType=VARCHAR}, nick = #{nick,jdbcType=VARCHAR}, gender = #{gender,jdbcType=INTEGER}, age = #{age,jdbcType=INTEGER}, head_img = #{headImg,jdbcType=VARCHAR}, phone = #{phone,jdbcType=VARCHAR}, `state` = #{state,jdbcType=INTEGER}, push_token = #{pushToken,jdbcType=VARCHAR}, app_salt = #{appSalt,jdbcType=VARCHAR}, web_salt = #{webSalt,jdbcType=VARCHAR}, enabled = #{enabled,jdbcType=BOOLEAN}, accountNonExpired = #{accountNonExpired,jdbcType=BOOLEAN}, accountNonLocked = #{accountNonLocked,jdbcType=BOOLEAN}, credentialsNonExpired = #{credentialsNonExpired,jdbcType=BOOLEAN}, create_time = #{createTime,jdbcType=DATE}, update_time = #{updateTime,jdbcType=DATE}, create_by = #{createBy,jdbcType=VARCHAR}, update_by = #{updateBy,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} 启动类
package com.baba.security.auth; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring boot app. * * @author wulongbo 2021/11/11 */ @SpringBootApplication(scanBasePackages = {"com.baba.security.common","com.baba.security.auth"}) @MapperScan("com.baba.security.auth.dao") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
测试

响应头中获取到 authorization 令牌。
我们输错地址看看有没有全局异常响应。

访问一下其他服务,在重新登录模拟挤号,在访问提示已在其他设备登录。


生成的jwt我们可以看看是啥样子的。
访问https://jwt.io/输入token,当然要把前六位(Bearer )去掉


说明
后面,我们再使用Oauth2.0来集成开放接口平台
到这里,我们也就讲完了《微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(3)》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于mysql的知识点!
ApacheCN 数据库译文集 20211112 更新
- 上一篇
- ApacheCN 数据库译文集 20211112 更新
- 下一篇
- 微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台
-
- 虚心的蜗牛
- 感谢大佬分享,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢老哥分享技术贴!
- 2023-03-13 09:43:16
-
- 天真的柚子
- 很详细,码住,感谢师傅的这篇技术文章,我会继续支持!
- 2023-02-28 01:27:34
-
- 淡淡的万宝路
- 这篇技术贴太及时了,很详细,真优秀,已收藏,关注博主了!希望博主能多写数据库相关的文章。
- 2023-02-27 06:08:46
-
- 谨慎的钥匙
- 这篇技术贴太及时了,大佬加油!
- 2023-02-25 13:42:12
-
- 数据库 · MySQL | 1小时前 | 性能优化 · 高并发 · InnoDB · MySQL教程 · 数据库运维 · mysql innodb AUTO_INCREMENT 高并发写入 innodb_autoinc_lock_mode
- MySQL 8.4 自增主键并发写入实战:AUTO_INCREMENT 锁模式别再凭感觉调
- 254浏览 收藏
-
- 数据库 · MySQL | 1小时前 | 连接池 · 高并发 · 故障排查 · MySQL教程 · 数据库运维 · mysql 高并发 连接池 max_connections Too many connections
- MySQL 8.4 连接池雪崩实战:Too many connections 不是把 max_connections 调大就完事
- 491浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 6159次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 6569次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 6374次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 8340次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 6985次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 分享Redis高可用架构设计实践
- 2023-01-24 286浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览

