什么是Api接口冪等?
大略來說Api接口冪等在有限的功夫內控制接口考察乞求,控制ip考察度數,不控制平臺考察,都不妨拿到數據。一個接口不不妨反復表單提交,消費一次耗費一次。
用戶場景:同一功夫反復提交屢次乞求。
什么是數據竄改?
api接口數據竄改,劇本文獻,竄改接口參數舉行效勞器數據奪取,重要的數據竄改會引導數據庫宕機,步調軟硬件解體。
想到這邊都領會后盾api接口冪等多要害了吧。即日給大師講非對稱加密實行后盾接口api冪等。
實行思緒:jtw+考證標識+出面密鑰+暫時功夫戳+寄存過時功夫+AES實行加密算法token。
實行辦法:1,用戶登錄勝利后,消費加密token寄存redis.
2,下次登錄檢查token能否過時,過時請從新登錄。
3,用戶登錄生存靈驗期,不須要登錄。(這邊即是單點登錄辦法)
code中心實行類:
importio.jsonwebtoken.*;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.security.authentication.UsernamePasswordAuthenticationToken;importorg.springframework.security.core.Authentication;importorg.springframework.security.core.GrantedAuthority;importorg.springframework.security.core.authority.SimpleGrantedAuthority;importorg.springframework.security.core.userdetails.User;importorg.springframework.stereotype.Component;importorg.springframework.util.StringUtils;importjavax.annotation.PostConstruct;importjavax.servlet.http.HttpServletRequest;importjava.util.*;importjava.util.stream.Collectors;@ComponentpublicclassJWTTokenUtils{publicstaticfinalStringAUTHORIZATION_HEADER="x-token";publicstaticfinalStringAUTHORIZATION_TOKEN="x-token";privatefinalLoggerlogger=LoggerFactory.getLogger(JWTTokenUtils.class);privatestaticfinalStringAUTHORITIES_KEY="auth";privateStringsecretKey;//出面密鑰privatelongtokenValidityInMilliseconds;//作廢日子privatelongtokenValidityInMillisecondsForRememberMe;//(記取我)作廢日子@PostConstructpublicvoidinit(){this.secretKey="isoftstone.huwei";intsecondIn1day=1000*60*60*24;this.tokenValidityInMilliseconds=secondIn1day*2L;this.tokenValidityInMillisecondsForRememberMe=secondIn1day*7L;}//創造TokenpublicStringcreateToken(Authenticationauthentication,BooleanrememberMe){Stringauthorities=authentication.getAuthorities().stream()//獲得用戶的權力字符串,如USER,ADMIN.map(GrantedAuthority::getAuthority).collect(Collectors.joining(","));longnow=(newDate()).getTime();//獲得暫時功夫戳Datevalidity;//寄存過時功夫if(rememberMe){validity=newDate(now+this.tokenValidityInMilliseconds);}else{validity=newDate(now+this.tokenValidityInMillisecondsForRememberMe);}returnSysConst.SYS_COMPANY_HEAD+"."+Jwts.builder()//創造Token令牌.setSubject(authentication.getName())//樹立面向用戶.claim(AUTHORITIES_KEY,authorities)//增添權力屬性.setExpiration(validity)//樹立作廢功夫.signWith(SignatureAlgorithm.HS512,secretKey)//天生出面.compact();}//獲得用戶權力publicAuthenticationgetAuthentication(Stringtoken){logger.info("JWTTokenUtilsStartGetUserAuth");//領會Token的payloadClaimsclaims=Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();Collection<?extendsGrantedAuthority>authorities=Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))//獲得用戶權力字符串.map(SimpleGrantedAuthority::new).collect(Collectors.toList());//將元素變換為GrantedAuthority接口匯合Userprincipal=newUser(claims.getSubject(),"",authorities);returnnewUsernamePasswordAuthenticationToken(principal,null,authorities);}/***領會token獲得用戶源代碼*@paramtoken*@return*/publicStringgetAuthSubject(Stringtoken){Claimsclaims=Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();returnclaims.getSubject();}publicStringresolveToken(HttpServletRequestrequest){StringbearerToken=request.getHeader(AUTHORIZATION_HEADER);//從HTTP頭部獲得TOKENif(StringUtils.hasText(bearerToken)&&bearerToken.startsWith(SysConst.SYS_COMPANY_HEAD)){returnbearerToken.substring(bearerToken.indexOf(".")+1,bearerToken.length());//歸來Token字符串,去除Bearer}Stringjwt=request.getParameter(AUTHORIZATION_TOKEN);//從乞求參數中獲得TOKENif(StringUtils.hasText(jwt)&&jwt.startsWith(SysConst.SYS_COMPANY_HEAD)){returnjwt.substring(bearerToken.indexOf(".")+1,jwt.length());}returnnull;}//考證Token能否精確publicbooleanvalidateToken(Stringtoken){try{Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);//經過密鑰考證Tokenreturntrue;}catch(MalformedJwtExceptione){//JWT***缺點logger.info("InvalidJWTtoken.");logger.trace("InvalidJWTtokentrace:{}",e);}catch(ExpiredJwtExceptione){//JWT過時logger.info("ExpiredJWTtoken.");logger.trace("ExpiredJWTtokentrace:{}",e);}catch(UnsupportedJwtExceptione){//不扶助該JWTlogger.info("UnsupportedJWTtoken.");logger.trace("UnsupportedJWTtokentrace:{}",e);}catch(IllegalArgumentExceptione){//參數缺點特殊logger.info("JWTtokencompactofhandlerareinvalid.");logger.trace("JWTtokencompactofhandlerareinvalidtrace:{}",e);}catch(SignatureExceptione){//出面特殊logger.info("InvalidJWTsignature.");logger.trace("InvalidJWTsignaturetrace:{}",e);}returnfalse;}}redis寫入緩存:
RedisModelmodel=newRedisModel();model.setModelName(token);model.setModelKey("userInfo");Map<String,Object>params=newHashMap<String,Object>();params.put("userName",customerDto.getUsername());CustomerVocustomerVo=newCustomerVo();customerVo.setEmail(customerDto.getEmail());customerVo.setPhone(customerDto.getPhone());CustomerVouserInfo=customerService.queryUserByUserName(customerVo);Map<String,Object>userToken=newHashMap<String,Object>();userToken.put("userToken",token);userToken.put("userInfo",userInfo);model.setModelData(userToken);model.setTimeoutType("M");model.setTimeout(redisTokenTimeOut);resultMap.setCode(CommonResultStatus.SUCCESS.getCode());resultMap.setMessage(CommonResultStatus.SUCCESS.getMessage());//寫入為hash實業redisTemplate.opsForHash().put(model.getModelName(),model.getModelKey(),model.getModelData());redisTemplate.expire(model.getModelName(),model.getTimeout(),TimeUnit.MINUTES);@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled=true)publicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{publicstaticfinalStringAUTHORIZATION_HEADER="x-token";//Authorization//承諾考察的路途privatestaticfinalString[]AUTH_WITHOUTLIST={//--swaggerui"/v2/api-docs","/swagger-resources","/swagger-resources/**","/configuration/ui","/configuration/security","/swagger-ui.html","/webjars/**",//otherpublicendpointsofyourAPImaybeappendedtothisarray"/druid/**","/health","/info","/info/**",//druidsql監聽"/hystrix","/hystrix/**","/error","/loggers","/loggers/**","/service-registry/instance-status","/hystrix.stream","/turbine/**","/turbine.stream","/autoconfig","/archaius","/beans","/features","/configprops","/mappings","/auditevents","/env","/env/**","/metrics","/metrics/**","/trace","/trace/**","/dump","/dump/**","/jolokia/**","/info/**","/activiti/**","/logfile/**","/refresh","/flyway/**","/liquibase/**","/heapdump","/heapdump/**","/v1/authcenter/login","/v1/authcenter/fiberhomeLogin","/v1/authcenter/registered",//登錄URL"/v1/authcenter/queryAuthInfo",//鑒權URL"/u/***s/sendPhone","/citry/getChineseProvinces","/code/getCaptchaImage","/u/***s/forgetEmailPwd","/u/***s/sendEmail","/citry/getOtherCoutryList","/upload/pngDir/*","/job/getJobList","/u/***s/sendLoginEmail","/v1/authcenter/queryUserInfoByMap","/v1/authcenter/forgetPwd","/diagram-viwmer/**","/editor-marketing/**","/modeler.html","/actuator/health"};@AutowiredprivateSecurityUserDetailsServicesecurityUserDetailsService;@AutowiredprivateAuthLogoutSuccessHandlerauthLogoutSuccessHandler;@AutowiredprivateJWTTokenUtilstokenProvider;@Overrideprotectedvoidconfigure(AuthenticationManagerBuilderauth)throwsException{//自設置獲得用戶消息樹立暗號加密和默許用DaoAuthenticationProvider加密任選auth.userDetailsService(securityUserDetailsService).passwordEncoder(passwordEncoder());}@Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException{//擺設乞求考察戰略//封閉CSRF、CORShttp.cors().disable().csrf().disable()//因為運用Token,以是不須要Session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()//考證Http乞求.authorizeRequests()//承諾一切用戶考察首頁與登錄.antMatchers(AUTH_WITHOUTLIST).permitAll()//其它任何乞求都要過程認證經過.anyRequest().authenticated().and()//用戶頁面須要用戶權力//樹立登出.logout().logoutSuccessHandler(authLogoutSuccessHandler).permitAll();//增添JWTfilter在http.addFilterBefore(newJwtAuthenticationTokenFilter(tokenProvider),UsernamePasswordAuthenticationFilter.class);}//確定能否有權力分三步后盾security仍舊對地方做了阻擋了,乞求頭必需樹立乞求參數參數1:確定token能否生存(security已實行)2:token能否靈驗(鑒于redis)3:考察API能否有權力緩存構造:
["java.util.HashMap",{"userToken":"ISOFTSTONE.eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI0MmRkMGJlZmQwNDg0MmMyODhiN2QxZjVkYTcwMWNjNiIsImF1dGgiOiJ1c2VyIiwiZXhwIjoxNjM1MjMyMzk4fQ.9VqMD0vyu-pe42moNd1QeNWP4KrBvvNYJKDQdQPDi_YKKXPG3l90dNn5wgK2rZXs471Pmeby-BdHPHd2-iNKfA","userInfo":["com.common.vo.CustomerVo",{"id":"42dd0befd04842c288b7d1f5da701cc6","createTime":["java.util.Date","2021-06-10"],"updateTime":["java.util.Date","2021-06-10"],"deleted":0,"phone":"13797004616","password":"123456","email":"sunlin@fiberhome.com","status":%