当前位置: 首页 > 后端技术 > Java

锋利的!我带的实习生集成SpringSecurity+JWT只需要四步就可以实现登录认证!

时间:2023-04-02 10:15:27 Java

灏忎簩鏄柊鏉ョ殑瀹炰範鐢熴€備綔涓烘妧鏈礋璐d汉锛屾垜杩樻槸寰堟湁璐d换鎰熺殑銆傛垜鎯虫妸涓€鍒囬兘褰掑拵浜庝粬銆傚晩锛屼笉瀵癸紝鎴戞€庝箞浼氫笉灏忓績璇村嚭蹇冮噷璇濆憿锛熷啀娆★紒灏忎簩鏄柊鏉ョ殑瀹炰範鐢熴€備綔涓烘妧鏈礋璐d汉锛屾垜杩樻槸寰堟湁璐d换鎰熺殑銆傚綋鎴戞湁浠€涔堝ソ浜嬬殑鏃跺€欙紝鎴戞€绘槸鎯宠捣浠栥€傝繖涓嶏紝鎴戝畨鎺掍簡涓€涓皬浠诲姟锛岄泦鎴怱pringSecurity+JWT瀹炵幇鐧诲綍璁よ瘉銆傛病鎯冲埌浠栧彧鐢ㄤ簡鍥涙灏辨悶瀹氫簡锛岃鎴戣寰楁洿鏈夐潰瀛愪簡銆?銆佸叧浜嶴pringSecurity鍦⊿pringBoot鍑虹幇涔嬪墠锛孲pringSecurity鐨勪娇鐢ㄥ満鏅鍙︿竴涓畨鍏ㄧ鐞嗘鏋禨hiro鐗㈢墷鍗犳嵁锛屽洜涓虹浉瀵逛簬SpringSecurity锛孲hiro鍦⊿SM涓殑闆嗘垚鏇翠负杞婚噺绾с€係pringBoot鍑虹幇鍚庯紝杩欑鎯呭喌鏈変簡寰堝ぇ鐨勬敼鍠勩€傛搴斾簡閭e彞鍙よ瘽锛氫竴浜烘垚閬撹櫧涓嶅Ε锛岀粓蹇呬笂澶┿€傝繖鏄洜涓篠pringBoot涓篠pringSecurity鎻愪緵浜嗚嚜鍔ㄩ厤缃紝澶уぇ闄嶄綆浜哠pringSecurity鐨勫涔犳垚鏈€傚彟澶栵紝SpringSecurity姣擲hiro鏇村己澶с€?銆佸叧浜嶫WTJWT鏄洰鍓嶆渶娴佽鐨勮法鍩熻璇佹柟妗堬細瀹㈡埛绔彂璧风敤鎴风櫥褰曡姹傦紝鏈嶅姟绔帴鏀跺苟璁よ瘉鎴愬姛鍚庯紝鐢熸垚涓€涓狫SON瀵硅薄锛堝涓嬪浘锛夛紝鐒跺悗杩斿洖缁欏鎴枫€備粠鏈川涓婅锛孞WT灏卞儚鏄敓鎴愬姞瀵嗙敤鎴疯韩浠戒俊鎭殑Token锛屾洿鍔犲畨鍏ㄧ伒娲汇€?.闆嗘垚姝ラ绗竴姝ユ槸涓洪渶瑕佺櫥褰曡璇佺殑妯″潡娣诲姞codingmore-security渚濊禆锛?dependency>top.codingmorecodingmore-security1.0-SNAPSHOT姣斿codingmore-admin鍚庡彴绠$悊妯″潡闇€瑕佺櫥褰曡璇侊紝鍦╟odingmore-admin/pom.xml鏂囦欢涓坊鍔燾odingmore-security渚濊禆銆傜浜屾锛屽湪闇€瑕佺櫥褰曡璇佺殑妯″潡涓坊鍔燙odingmoreSecurityConfig绫伙紝璇ョ被缁ф壙鑷猚odingmore-security妯″潡涓殑SecurityConfig绫汇€侤Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled=true)publicclassCodingmoreSecurityConfigextendsSecurityConfig{@AutowiredprivateIUsersServiceusersService;@BeanpublicUserDetailsS鈥嬧€媏rviceuserDetailsS鈥嬧€媏rvice(){//鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅returnusername->usersname);User}.loadUserDetailsS鈥嬧€媏rvice璇ョ被涓昏鐢ㄤ簬鍔犺浇鐢ㄦ埛淇℃伅锛屽寘鎷敤鎴峰悕銆佸瘑鐮併€佹潈闄愩€佽鑹查泦鍚堛€傚叾涓竴绉嶆柟娉曞涓嬶細UserDetailsloadUserByUsername(Stringusername)throwsUsernameNotFoundException;鍦ㄨ璇侀€昏緫涓紝SpringSecurity浼氳皟鐢ㄨ鏂规硶鏍规嵁瀹㈡埛绔紶鍏ョ殑鐢ㄦ埛鍚嶅姞杞界敤鎴风殑璇︾粏淇℃伅锛屽寘鎷垽鏂瘑鐮佹槸鍚︿竴鑷达紝浼犻€掕幏鍙栨潈闄愬拰瑙掕壊publicUserDetailsloadUserByUsername(Stringusername){//鏌ヨ鍩轰簬鐢ㄦ埛鍚嶇殑鐢ㄦ埛Usersadmin=getAdminByUsername(username);if(admin!=null){ListresourceList=getResourceList(admin.getId());杩斿洖鏂扮殑AdminUserDetails(admin,resourceList);}thrownewUsernameNotFoundException("鐢ㄦ埛鍚嶆垨瀵嗙爜閿欒");}getAdminByUSername璐熻矗鏍规嵁鐢ㄦ埛鍚嶄粠鏁版嵁搴撲腑鏌ヨ瀵嗙爜銆佽鑹层€佹潈闄愮瓑publicUsersgetAdminByUsername(Stringusername){QueryWrapperqueryWrapper=newQueryWrapper<>();queryWrapper.eq("user_login",鐢ㄦ埛鍚?;ListusersList=baseMapper.selectList(queryWrapper);if(usersList!=null&&usersList.size()>0){returnusersList.get(0);}//鐢ㄦ埛鍚嶉敊璇紝鎻愬墠鎶涘嚭寮傚父thrownewUsernameNotFoundException("鐢ㄦ埛鍚嶉敊璇?);绗笁姝ュ湪application.yml涓厤缃笉闇€瑕佸畨鍏ㄤ繚鎶ょ殑璧勬簮璺緞锛歴ecure:ignored:urls:#Securitypathwhitelist-/doc.html-/swagger-ui/**-/swagger/**-/swagger-resources/**-/**/v3/api-docs-/**/*.js-/**/*.css-/**/*.png-/**/*.ico-/webjars/springfox-swagger-ui/**-/actuator/**-/druid/**-/users/login-/users/register-/users/info-/users/logout绗洓姝ユ坊鍔犵櫥褰曠晫闈腑鐨勭櫥褰曞拰鍒锋柊浠ょ墝鏂规硶锛欯Controller@Api(tags="User")@RequestMapping("/users")鍏叡绫籙sersController{@AutowiredprivateIUsersServiceusersService;@Value("${jwt.tokenHeader}")privateStringtokenHeader;@Value("${jwt.tokenHead}")privateStringtokenHead;@ApiOperation(value="鐧诲綍浠ュ悗杩斿洖token")@RequestMapping(value="/login",method=RequestMethod.POST)@ResponseBodypublicResultObjectlogin(@ValidatedUsersLoginParamusers,BindingResultresult){Stringtoken=usersService.login(users.getUserLogin(),users.getUserPass());if(token==null){returnResultObject.validateFailed("鐢ㄦ埛鍚嶆垨瀵嗙爜閿欒");}//灏咼WT浼犲洖瀹㈡埛绔疢aptokenMap=newHashMap<>();tokenMap.put("token",token);tokenMap.put("tokenHead",tokenHead);returnResultObject.success(tokenMap);}@ApiOperation(value="鍒锋柊token")@RequestMapping(value="/refreshToken",method=RequestMethod.GET)@ResponseBodypublicResultObjectrefreshToken(HttpServletRequestrequest){Stringtoken=request.getHeader(tokenHeader);}StringrefreshToken=usersService.refreshToken(token);if(==refreshToknull){returnResultObject.failed("tokenhasexpired!");}MaptokenMap=newHashMap<>();tokenMap.put("浠ょ墝",refreshToken);tokenMap.put("tokenHead",tokenHead);杩斿洖ResultObject.success(tokenMap);}}浣跨敤Apipost杩涜娴嬭瘯锛岄鍏堟槸鏂囩珷鑾峰彇鎺ュ彛锛屽鏋滄病鏈夌櫥褰曪紝浼氭彁绀烘病鏈夌櫥褰曟垨鑰卼oken杩囨湡鐧诲綍璁よ瘉鍙渶瑕佸洓姝ュ氨瀹炵幇浜嗭紝涓昏鏄粬灏佽浜嗗皢SpringSecurity+JWT鐨勪唬鐮佸悎骞舵垚涓€涓€氱敤妯″潡銆傛垜浠潵鐪嬬湅codingmore-security鐨勭洰褰曠粨鏋勩€俢odingmore-security鈹溾攢鈹€缁勪欢|鈹溾攢鈹€JwtAuthenticationTokenFilter--JWT鐧诲綍鎺堟潈杩囨护鍣▅鈹溾攢鈹€RestAuthenticationEntryPoint|鈹斺攢鈹€RestfulAccessDeniedHandler鈹溾攢鈹€閰嶇疆|鈹溾攢鈹€IgnoreUrlsConfig|鈹斺攢鈹€SecurityConfig鈹斺攢鈹€util鈹斺攢鈹€JwtTokenUtil--JWT鐨則oken澶勭悊宸ュ叿绫籎wtAuthenticationTokenFilter鍜孞wtTokenUtil鍦ㄨJWT鐨勬椂鍊欏凡缁忚缁嗚杩囦簡锛岃繖閲岀畝鍗曡ˉ鍏呬竴涓嬨€傚鎴风鐨勮姹傚ご鎼哄甫token锛屾湇鍔$姣忔璇锋眰閮借瑙f瀽鍜岄獙璇乼oken锛屾墍浠ュ繀椤诲畾涔変竴涓繃婊ゅ櫒锛屽嵆JwtAuthenticationTokenFilter锛氫粠璇锋眰澶翠腑鑾峰彇token杩涜瑙f瀽锛岄獙璇乼oken锛孷erifythatthe杩囨湡鏃堕棿楠岃瘉鎴愬姛锛屽皢楠岃瘉缁撴灉鏀惧叆ThreadLocal锛屼緵涓嬫璇锋眰浣跨敤銆備笓娉ㄤ簬鍏朵粬鍥涗釜绫汇€傜涓€涓猂estAuthenticationEntryPoint锛堣嚜瀹氫箟杩斿洖缁撴灉锛氭湭鐧诲綍鎴栫櫥褰曡繃鏈燂級锛歱ublicclassRestAuthenticationEntryPointimplementsAuthenticationEntryPoint{@Overridepublicvoidcommine(HttpServletRequestrequest,HttpServletResponseresponse,AuthenticationExceptionauthException)throwsIOException",ServletCesser-response{鎺у埗鍏佽鏉ユ簮","*");response.setHeader("缂撳瓨鎺у埗","鏃犵紦瀛?);response.setCharacterEncoding("UTF-8");response.setContentType("application/json");response.getWriter().println(JSONUtil.parse(ResultObject.unauthorized(authException.getMessage())));response.getWriter().flush();}}鍙互閫氳繃璋冭瘯鐢ㄦ埛鏈櫥褰曡闂枃绔犻〉闈㈡椂鐨凟rrormessage鏌ョ湅杩斿洖淇℃伅銆傚叿浣撲俊鎭畾涔夊湪ResultCode绫讳腑銆俻ublicenumResultCodeimplementsIErrorCode{SUCCESS(0,"鎿嶄綔鎴愬姛"),FAILED(500,"鎿嶄綔澶辫触"),VALIDATE_FAILED(506,"鍙傛暟楠岃瘉澶辫触"),UNAUTHORIZED(401,"灏氭湭鐧诲綍鎴栦护鐗屽凡杩囨湡"),FORBIDDEN(403,"鏃犵浉鍏虫潈闄?);绉佹湁闀跨爜锛涚浜哄瓧绗︿覆娑堟伅锛沺rivateResultCode(longcode,Stringmessage){this.code=code;this.message=娑堟伅锛泒}绗簩涓猂estfulAccessDeniedHandler(鑷畾涔夎繑鍥炵粨鏋滐細璁块棶鏈巿鏉冩椂):publicclassRestfulAccessDeniedHandlerimplementsAccessDeniedHandler{@Overridepublicvoidhandle(HttpServletRequestrequest,HttpServletResponseresponse,AccessDeniedExceptione)throwsIOException,ServletException("Control-Access-Ogin"{response.setHead,"*");response.setHeader("缂撳瓨鎺у埗","鏃犵紦瀛?);response.setCharacterEncoding("UTF-8");鍥炲.setContentType("搴旂敤绋嬪簭/json");response.getWriter().println(JSONUtil.parse(ResultObject.forbidden(e.getMessage())));response.getWriter().flush();}}绗笁涓狪gnoreUrlsConfig锛堢敤浜庨厤缃笉闇€瑕佸畨鍏ㄤ繚鎶ょ殑璧勬簮璺緞锛夛細@Getter@Setter@ConfigurationProperties(prefix="secure.ignored")publicclassIgnoreUrlsConfig{privateListurls=newArrayList<>();}閫氳繃lombok娉ㄨВ鏂瑰紡鐩存帴閲婃斁閰嶇疆鏂囦欢涓笉闇€瑕佹潈闄愰獙璇佺殑璺緞銆傛瘮濡侹nife4j鐨勬帴鍙f枃妗i〉闈笉鍙戝竷锛屽氨浼氳SpringSecurity鎷︽埅锛屾棤娉曡闂€傜鍥涗釜SecurityConfig锛圫pringSecurity閫氱敤閰嶇疆锛夛細publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@Autowired(required=false)privateDynamicSecurityServicedynamicSecurityService;@Overrideprotectedvoidconfigure(HttpSecurityhttpSecurity)鎶涘嚭寮傚父//鍏佽涓嶉渶瑕佷繚鎶ょ殑璧勬簮璺緞璁块棶for(Stringurl:ignoreUrlsConfig().getUrls()){registry.antMatchers(url).permitAll();}//浠讳綍璇锋眰閮介渶瑕佽韩浠介獙璇乺egistry.and().authorizeRequests().anyRequest().authenticated()//鍏抽棴璺ㄧ珯璇锋眰淇濇姢锛屼笉浣跨敤浼氳瘽.and().csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)//鏉ヨ嚜DefinepermissiondenialsHandlingclass.and().exceptionHandling().accessDeniedHandler(restfulAccessDeniedHandler()).authenticationEntryPoint(restAuthenticationEntryPoint())//鑷畾涔夋潈闄愭嫤鎴櫒JWTfilter.and().addFilterBefore(jwtAuthenticationTokenFilter(),UsernamePasswordAuthenticationFilter.class);//鏈夊姩鎬佹潈闄愰厤缃椂娣诲姞鍔ㄦ€佹潈闄愰獙璇佽繃婊ゅ櫒}}}杩欎釜绫荤殑涓昏浣滅敤灏辨槸鍛婅瘔SpringSecurity閭d簺璺緞涓嶉渶瑕佹嫤鎴€傚惁鍒欙紝蹇呴』鎵цRestfulAccessDeniedHandler锛堢櫥褰曢獙璇侊級銆丷estAuthenticationEntryPoint锛堟潈闄愰獙璇侊級鍜孞wtAuthenticationTokenFilter锛圝WT杩囨护锛夛紝骞跺湪UsernamePasswordAuthenticationFilter杩囨护鍣ㄤ箣鍓嶆坊鍔燡wtAuthenticationTokenFilter杩囨护鍣ㄣ€?.娴嬭瘯绗竴姝ユ槸娴嬭瘯鐧诲綍鐣岄潰銆俛pipost鐩存帴璁块棶http://localhost:9002/users/login锛屽彲浠ョ湅鍒皌oken姝e父杩斿洖銆傜浜屾锛屾棤闇€token锛岀洿鎺ヨ闂枃绔犵晫闈€傚彲浠ョ湅鍒癛estAuthenticationEntryPoint澶勭悊鍣ㄨ繘鍏ヤ簡锛氱涓夋锛屾惡甯oken銆傝繖娆℃垜浠娇鐢↘nife4j杩涜娴嬭瘯锛屽彂鐜板彲浠ユ甯歌闂細婧愮爜閾炬帴锛歨ttps://github.com/itwanger/coding-more鏈枃宸茶寮€婧愪笓鏍忋€奐ava 绋嬪簭鍛樿繘闃朵箣璺€嬫敹褰?.9k+star鍦℅itHub涓娿€傛嵁璇存瘡涓€涓紭绉€鐨凧ava绋嬪簭鍛橀兘鍠滄濂癸紝濂瑰菇榛橀瓒o紝閫氫織鏄撴噦銆傚唴瀹瑰寘鎷琂ava鍩虹銆丣ava骞跺彂缂栫▼銆丣ava铏氭嫙鏈恒€丣ava浼佷笟绾у紑鍙戙€丣ava闈㈣瘯绛夋牳蹇冪煡璇嗙偣銆傚涔燡ava锛屽彧涓哄鎵綣ava绋嬪簭鍛樼殑杩涢樁涔嬭矾馃槃銆俬ttps://github.com/itwanger/toBeBetterJavaerstar杩欎釜瀛樺偍搴撴剰鍛崇潃浣犳湁娼滃姏鎴愪负涓€鍚嶄紭绉€鐨凧ava宸ョ▼甯堛€備篃鍙互鐐瑰嚮涓嬫柟閾炬帴璺宠浆鍒般€奐ava 绋嬪簭鍛樿繘闃朵箣璺€嬪畼缃戯紝寮€鍚剦蹇殑瀛︿範涔嬫梾銆俬ttps://tobebetterjavaer.com/娌℃湁浠€涔堣兘闃绘鎴戔€斺€旈櫎浜嗙洰鐨勶紝鍗充娇宀歌竟鏈夌帿鐟般€佺豢鑽拰瀹侀潤鐨勬腐婀撅紝鎴戜篃涓嶅彈鏉熺細銆?/p>