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

东营网站建设服务商网站建设合同书

东营网站建设服务商,网站建设合同书,有赞微商城小程序,做外贸对学历要求高吗目录 1. 数据库设计 2. 代码设计 登录认证过滤器 认证成功处理器AuthenticationSuccessHandler 认证失败处理器AuthenticationFailureHandler AuthenticationEntryPoint配置 AccessDeniedHandler配置 UserDetailsService配置 Token校验过滤器 登录认证过滤器接口配置…目录 1. 数据库设计 2. 代码设计 登录认证过滤器 认证成功处理器AuthenticationSuccessHandler 认证失败处理器AuthenticationFailureHandler AuthenticationEntryPoint配置 AccessDeniedHandler配置 UserDetailsService配置 Token校验过滤器 登录认证过滤器接口配置 Spring Security全局配置 util包 测试结果 在SpringSecurity实现前后端分离登录token认证详解_springsecurity前后端分离登录认证-CSDN博客基础上进行重构实现前后端分离架构登录认证基本思想相同借鉴开源Gitee代码进行改造具有更好的代码规范。 1. 数据库设计 DROP TABLE IF EXISTS t_auth; CREATE TABLE t_auth (id BIGINT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 名称,url VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 路径,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB AUTO_INCREMENT 7 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_auth -- ---------------------------- INSERT INTO t_auth VALUES (1, 删除用户, /usr/del, 1, 2021-11-26 17:08:11, 2021-11-26 17:07:52); INSERT INTO t_auth VALUES (2, 新增用户, /usr/add, 1, 2021-11-26 17:08:13, 2021-11-26 17:08:09); INSERT INTO t_auth VALUES (3, 添加产品, /product/add, 1, 2021-11-26 17:08:42, 2021-11-26 17:08:29); INSERT INTO t_auth VALUES (4, 下架产品, /product/del, NULL, NULL, 2021-11-26 17:12:17); INSERT INTO t_auth VALUES (5, 注册, /user/register, NULL, NULL, 2021-11-26 17:13:32); INSERT INTO t_auth VALUES (6, 注销, /user/logOff, NULL, NULL, 2021-11-26 17:13:50);-- ---------------------------- -- Table structure for t_role -- ---------------------------- DROP TABLE IF EXISTS t_role; CREATE TABLE t_role (id BIGINT(11) NOT NULL,name VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 角色名称,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_role -- ---------------------------- INSERT INTO t_role VALUES (1, ROLE_admin, 1, 2021-11-26 17:08:52, 2021-11-26 17:08:51); INSERT INTO t_role VALUES (2, ROLE_dba, 1, 2021-11-26 17:09:10, 2021-11-26 17:09:05); INSERT INTO t_role VALUES (3, ROLE_vip, 1, 2021-11-26 17:09:32, 2021-11-26 17:09:25); INSERT INTO t_role VALUES (4, ROLE_user, 1, 2021-11-26 17:09:45, 2021-11-26 17:09:42);-- ---------------------------- -- Table structure for t_role_auth -- ---------------------------- DROP TABLE IF EXISTS t_role_auth; CREATE TABLE t_role_auth (id BIGINT(20) NOT NULL AUTO_INCREMENT,role_id BIGINT(20) NULL DEFAULT NULL,auth_id BIGINT(20) NULL DEFAULT NULL,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB AUTO_INCREMENT 5 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_role_auth -- ---------------------------- INSERT INTO t_role_auth VALUES (1, 1, 3, 1, 2021-11-26 17:11:31, 2021-11-26 17:11:29); INSERT INTO t_role_auth VALUES (2, 1, 4, 1, 2021-11-26 17:11:31, 2021-11-26 17:11:29); INSERT INTO t_role_auth VALUES (3, 4, 5, 1, 2021-11-26 17:14:45, 2021-11-26 17:14:35); INSERT INTO t_role_auth VALUES (4, 4, 6, 1, 2021-11-26 17:14:47, 2021-11-26 17:14:41);-- ---------------------------- -- Table structure for t_user -- ---------------------------- DROP TABLE IF EXISTS t_user; CREATE TABLE t_user (id BIGINT(11) NOT NULL,user_id VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 唯一的userId,username VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 用户名,password VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 密码,name VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 姓名,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_user -- ---------------------------- INSERT INTO t_user VALUES (1, 120, zhangsan, 123456, 张三, 1, 2021-11-26 17:07:03, 2021-11-26 17:06:53); INSERT INTO t_user VALUES (2, 110, lisi, 123456, 李四, 1, 2021-11-26 17:07:36, 2021-11-26 17:07:12);-- ---------------------------- -- Table structure for t_user_role -- ---------------------------- DROP TABLE IF EXISTS t_user_role; CREATE TABLE t_user_role (id BIGINT(20) NOT NULL AUTO_INCREMENT,user_id VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 用户唯一userId,role_id BIGINT(20) NULL DEFAULT NULL,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB AUTO_INCREMENT 3 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_user_role -- ---------------------------- INSERT INTO t_user_role VALUES (1, 120, 1, 1, 2021-11-26 17:10:10, 2021-11-26 17:10:11); INSERT INTO t_user_role VALUES (2, 110, 2, 1, 2021-11-26 17:11:16, 2021-11-26 17:11:13); 2. 代码设计 登录认证过滤器 Spring Security默认的表单登录认证的过滤器是UsernamePasswordAuthenticationFilter这个过滤器并不适用于前后端分离的架构因此我们需要自定义一个过滤器。参照UsernamePasswordAuthenticationFilter这个过滤器改造一下。 /*** 登录认证的filter参照UsernamePasswordAuthenticationFilter添加到这之前的过滤器*/public class JwtAuthenticationLoginFilter extends AbstractAuthenticationProcessingFilter {/*** 构造方法调用父类的设置登录地址/login请求方式POST*/public JwtAuthenticationLoginFilter() {super(new AntPathRequestMatcher(/login, POST));}Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {//获取表单提交数据String username request.getParameter(username);String password request.getParameter(password);//封装到token中提交UsernamePasswordAuthenticationToken authRequest new UsernamePasswordAuthenticationToken(username,password);return getAuthenticationManager().authenticate(authRequest);} } 认证成功处理器AuthenticationSuccessHandler 上述的过滤器接口一旦认证成功则会调用AuthenticationSuccessHandler进行处理因此我们可以自定义一个认证成功处理器进行自己的业务处理代码如下 Component public class LoginAuthenticationSuccessHandler implements AuthenticationSuccessHandler {Autowiredprivate JwtUtil jwtUtil;AutowiredRedisTemplate redisTemplate;Overridepublic void onAuthenticationSuccess(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,Authentication authentication) throws IOException {UserDetails userDetails (UserDetails) authentication.getPrincipal();SecurityContextHolder.getContext().setAuthentication(authentication);MapString,String mapnew HashMap();map.put(username,userDetails.getUsername());//jwt生成tokenString token jwtUtil.getToken(map);RedisUser redisUser RedisUser.builder().username(userDetails.getUsername()).password(userDetails.getPassword()).authorities(userDetails.getAuthorities().stream().map(i-i.getAuthority()).collect(Collectors.toList())).build();//将用户信息保存到redis缓存中redisTemplate.opsForValue().set(userDetails.getUsername(),redisUser,12, TimeUnit.HOURS);ResponseUtils.result(httpServletResponse,new ResultMsg(200,登录成功,token));}} 认证失败处理器AuthenticationFailureHandler 同样的一旦登录失败比如用户名或者密码错误等等则会调用AuthenticationFailureHandler进行处理因此我们需要自定义一个认证失败的处理器其中根据异常信息返回特定的JSON数据给客户端代码如下 Component public class LoginAuthenticationFailureHandler implements AuthenticationFailureHandler {/*** 一旦登录失败则会被调用*/Overridepublic void onAuthenticationFailure(HttpServletRequest httpServletRequest,HttpServletResponse response,AuthenticationException exception) throws IOException {//TODO 根据项目需要返回指定异常提示,这里演示了一个用户名密码错误的异常//BadCredentialsException 这个异常一般是用户名或者密码错误if (exception instanceof BadCredentialsException){ResponseUtils.result(response,new ResultMsg(200,用户名或密码不正确,null));}ResponseUtils.result(response,new ResultMsg(200,登录失败,null));} } AuthenticationEntryPoint配置 AuthenticationEntryPoint这个接口当用户未通过认证访问受保护的资源时将会调用其中的commence()方法进行处理。 Component Slf4j public class EntryPointUnauthorizedHandler implements AuthenticationEntryPoint {Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {ResponseUtils.result(response,new ResultMsg(403,认证失败请重新登录,null));} } AccessDeniedHandler配置 AccessDeniedHandler这处理器当认证成功的用户访问受保护的资源但是权限不够则会进入这个处理器进行处理。 Component public class RequestAccessDeniedHandler implements AccessDeniedHandler {Overridepublic void handle(HttpServletRequest request,HttpServletResponse response,AccessDeniedException accessDeniedException) throws IOException {ResponseUtils.result(response,new ResultMsg(403,权限不足,null));} } UserDetailsService配置 UserDetailsService这个类是用来加载用户信息包括用户名、密码、权限、角色集合我们需要实现这个接口从数据库加载用户信息代码如下 Service public class JwtTokenUserDetailsService implements UserDetailsService {/*** 查询用户详情的service*/Autowiredprivate LoginService loginService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//从数据库中查询SecurityUser securityUser loginService.loadByUsername(username);System.out.println(securityUser);//用户不存在直接抛出UsernameNotFoundExceptionsecurity会捕获抛出BadCredentialsExceptionif (Objects.isNull(securityUser))throw new UsernameNotFoundException(用户不存在);return securityUser;} } 其中的LoginService是根据用户名从数据库中查询出密码、角色、权限代码如下 Service public class LoginServiceImpl implements LoginService {Autowiredprivate PasswordEncoder passwordEncoder;AutowiredTUserService tUserService;AutowiredTRoleService tRoleService;NullableOverridepublic SecurityUser loadByUsername(String username) {//获取用户信息TUser user tUserService.getByUsername(username);if (Objects.nonNull(user)){SecurityUser securityUser new SecurityUser();securityUser.setUsername(username);//todo 此处为了方便直接在数据库存储的明文实际生产中应该存储密文则这里不用再次加密securityUser.setPassword(passwordEncoder.encode(user.getPassword()));//查询该用户的角色ListString userRoles tRoleService.selectAllByUsername(username);String[] a{};ListGrantedAuthority authorityList AuthorityUtils.createAuthorityList(userRoles.toArray(a));securityUser.setAuthorities(authorityList);return securityUser;}return null;}}UserDetails这个也是个接口其中定义了几种方法都是围绕着用户名、密码、权限角色集合这三个属性因此我们可以实现这个类拓展这些字段SecurityUser代码如下 Data public class SecurityUser implements UserDetails {//用户名private String username;//密码private String password;//权限private Collection? extends GrantedAuthority authorities;public SecurityUser(String username, String password, Collection? extends GrantedAuthority authorities) {this.username username;this.password password;this.authorities authorities;}public SecurityUser(){}Overridepublic Collection? extends GrantedAuthority getAuthorities() {return authorities;}Overridepublic String getPassword() {return password;}Overridepublic String getUsername() {return username;}// 账户是否未过期Overridepublic boolean isAccountNonExpired() {return true;}// 账户是否未被锁Overridepublic boolean isAccountNonLocked() {return true;}Overridepublic boolean isCredentialsNonExpired() {return true;}Overridepublic boolean isEnabled() {return true;} } Token校验过滤器 客户端请求头携带了token服务端肯定是需要针对每次请求解析、校验token因此必须定义一个Token过滤器这个过滤器的主要逻辑如下 从请求头中获取accessToken 对accessToken解析、验签、校验过期时间 校验成功将authentication存入ThreadLocal中这样方便后续直接获取用户详细信息。 Component public class TokenAuthenticationFilter extends OncePerRequestFilter {/*** JWT的工具类*/Autowiredprivate JwtUtil jwtUtil;/*** UserDetailsService的实现类从数据库中加载用户详细信息*/Qualifier(jwtTokenUserDetailsService)Autowiredprivate UserDetailsService userDetailsService;AutowiredRedisTemplate redisTemplate;Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {String token request.getHeader(token);/*** token存在则校验token* 1. token是否存在* 2. token存在* 2.1 校验token中的用户名是否失效*/if (!StringUtils.isEmpty(token)){DecodedJWT decodedJWT jwtUtil.getTokenInfo(token);String username;try {username decodedJWT.getClaim(username).asString();}catch (Exception e){throw new RuntimeException(token无效);}//从redis缓存中获得对应用户数据RedisUser redisUser (RedisUser) redisTemplate.opsForValue().get(username);String[] a{};ListGrantedAuthority authorityList AuthorityUtils.createAuthorityList(redisUser.getAuthorities().toArray(a));UsernamePasswordAuthenticationToken authentication new UsernamePasswordAuthenticationToken(redisUser, null,authorityList);authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));// 将 authentication 存入 ThreadLocal方便后续获取用户信息SecurityContextHolder.getContext().setAuthentication(authentication);}//继续执行下一个过滤器chain.doFilter(request,response);} } 登录认证过滤器接口配置 上述定义了一个认证过滤器JwtAuthenticationLoginFilter这个是用来登录的过滤器但是并没有注入加入Spring Security的过滤器链中需要定义配置代码如下 Configuration public class JwtAuthenticationSecurityConfig extends SecurityConfigurerAdapterDefaultSecurityFilterChain, HttpSecurity {/*** userDetailService*/Qualifier(jwtTokenUserDetailsService)Autowiredprivate UserDetailsService userDetailsService;/*** 登录成功处理器*/Autowiredprivate LoginAuthenticationSuccessHandler loginAuthenticationSuccessHandler;/*** 登录失败处理器*/Autowiredprivate LoginAuthenticationFailureHandler loginAuthenticationFailureHandler;/*** 加密*/Autowiredprivate PasswordEncoder passwordEncoder;/*** 将登录接口的过滤器配置到过滤器链中* 1. 配置登录成功、失败处理器* 2. 配置自定义的userDetailService从数据库中获取用户数据* 3. 将自定义的过滤器配置到spring security的过滤器链中配置在UsernamePasswordAuthenticationFilter之前* param*/Overridepublic void configure(HttpSecurity http) {JwtAuthenticationLoginFilter filter new JwtAuthenticationLoginFilter();filter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));//认证成功处理器filter.setAuthenticationSuccessHandler(loginAuthenticationSuccessHandler);//认证失败处理器filter.setAuthenticationFailureHandler(loginAuthenticationFailureHandler);//直接使用DaoAuthenticationProviderDaoAuthenticationProvider provider new DaoAuthenticationProvider();//设置userDetailServiceprovider.setUserDetailsService(userDetailsService);//设置加密算法provider.setPasswordEncoder(passwordEncoder);http.authenticationProvider(provider);//将这个过滤器添加到UsernamePasswordAuthenticationFilter之前执行http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);} } Spring Security全局配置 上述仅仅配置了登录过滤器还需要在全局配置类做一些配置如下 应用登录过滤器的配置 将登录接口、令牌刷新接口放行不需要拦截 配置AuthenticationEntryPoint、AccessDeniedHandler 禁用session前后端分离JWT方式不需要session 将token校验过滤器TokenAuthenticationFilter添加到过滤器链中放在UsernamePasswordAuthenticationFilter之前。 Configuration //EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {Autowiredprivate JwtAuthenticationSecurityConfig jwtAuthenticationSecurityConfig;Autowiredprivate EntryPointUnauthorizedHandler entryPointUnauthorizedHandler;Autowiredprivate RequestAccessDeniedHandler requestAccessDeniedHandler;Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin()//禁用表单登录前后端分离用不上.disable()//应用登录过滤器的配置配置分离.apply(jwtAuthenticationSecurityConfig).and()// 设置URL的授权.authorizeRequests().antMatchers(/login).permitAll()// anyRequest() 所有请求 authenticated() 必须被认证.anyRequest().authenticated()//处理异常情况认证失败和权限不足.and().exceptionHandling()//认证未通过不允许访问异常处理器.authenticationEntryPoint(entryPointUnauthorizedHandler)//认证通过但是没权限处理器.accessDeniedHandler(requestAccessDeniedHandler).and()//禁用sessionJWT校验不需要session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()//将TOKEN校验过滤器配置到过滤器链中否则不生效放到UsernamePasswordAuthenticationFilter之前.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)// 关闭csrf.csrf().disable();}// 自定义的Jwt Token校验过滤器Beanpublic TokenAuthenticationFilter authenticationTokenFilterBean() {return new TokenAuthenticationFilter();}/*** 加密算法** return*/BeanOverrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();} } util包 JWT工具类 Component ConfigurationProperties(prefix jwt) //Data public class JwtUtil {private String signaturecbac;private Integer expiration12;/**** 生成token header.payload.signature*/public String getToken(MapString,String payload){Calendar calendar Calendar.getInstance();calendar.add(Calendar.HOUR, 24); // 24小时JWTCreator.Builder builder JWT.create();// 构建payloadpayload.forEach(builder::withClaim);// 指定签发时间、过期时间 和 签名算法并返回tokenString token builder.withIssuedAt(new Date()).withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(signature));return token;}/**** 获取token信息*/public DecodedJWT getTokenInfo(String token){DecodedJWT verifyJWT.require(Algorithm.HMAC256(signature)).build().verify(token);return verify;}} 结果封装类 public class ResponseUtils {public static void result(HttpServletResponse response, ResultMsg msg) throws IOException {response.setContentType(application/json;charsetUTF-8);ServletOutputStream out response.getOutputStream();ObjectMapper objectMapper new ObjectMapper();out.write(objectMapper.writeValueAsString(msg).getBytes(UTF-8));out.flush();out.close();} }测试结果 项目目录结构
http://www.dnsts.com.cn/news/86437.html

相关文章:

  • 靖江有哪些做网站的如何自己做网页
  • 做黑彩网站图片牡丹江百姓网免费发布信息
  • 南宁学网站建设网页设计师作品集
  • wordpress主题站模板wordpress网站建设教程
  • 房地产开发公司网站建设方案做网站优化费用
  • 有没有做面粉美食的网站中国移动积分兑换商城官方网站
  • 品牌网站建设仁術大蝌蚪铜梁城乡建设网站
  • 免费的开源网站网站电话素材
  • 移动微网站网站页面优化
  • 网站信息内容建设自查报告电子商城网站开发支持手机端
  • 兰溪网站seo 百度网盘
  • 网站如何做好优化仿网站出售
  • 邹平网站设计网站色彩运用
  • 创新的邯郸网站建设wdcp 网站建设
  • 淘宝网站建设费用网络架构要求包括
  • 网站改版意见微软软件开发工程师待遇
  • 微网站开发协议wordpress格式化sql串
  • 事务所网站建设如何取消网站备案
  • 网站设计一般是什么专业seo做什么网站赚钱
  • 河南电力建设工程公司网站网站建设销售实训报告
  • 有哪些免费的视频网站广告公司简介ppt
  • 学习怎样建网站青海省教育厅门户网站官网
  • 网站设计专家微信小程序公司网站怎么制作
  • 网站建设素材包娄底市建设网站
  • 五指山网站开发价格宁波设计网站公司
  • 网站产品简介怎样用编程语言做网站
  • wordpress被镜像有了网站后台后怎么做seo优化
  • 买做指甲的材料在哪个网站教学督导网站建设报告
  • 品牌案例网站物流信息网站cms
  • 做旅游宣传网站的流程图百度网站的优势