誰(shuí)用fun域名做網(wǎng)站了網(wǎng)站如何優(yōu)化關(guān)鍵詞排名
Hi I’m Shendi
快速開(kāi)發(fā)框架若依的基礎(chǔ)使用詳解
最近在為公司制作新的項(xiàng)目,經(jīng)過(guò)了一段時(shí)間的技術(shù)沉淀,我開(kāi)始嘗試接觸市面上用的比較多的快速開(kāi)發(fā)框架,聽(tīng)的最多的當(dāng)屬若依吧
于是就選用了若依
介紹
為什么選?目的是為了提高開(kāi)發(fā)效率,至于能不能提高,得實(shí)踐才能知曉。
若依的官網(wǎng):http://www.ruoyi.vip/
是一個(gè)快速開(kāi)發(fā)框架,典型的一個(gè)后臺(tái)管理系統(tǒng)。
RuoYi-Vue 是一個(gè) Java EE 企業(yè)級(jí)快速開(kāi)發(fā)平臺(tái),基于經(jīng)典技術(shù)組合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),內(nèi)置模塊如:部門(mén)管理、角色用戶(hù)、菜單及按鈕授權(quán)、數(shù)據(jù)權(quán)限、系統(tǒng)參數(shù)、日志管理、代碼生成等。在線(xiàn)定時(shí)任務(wù)配置;支持集群,支持多數(shù)據(jù)源,支持分布式事務(wù)。
可以通過(guò)官網(wǎng)的在線(xiàn)演示看到效果,當(dāng)然,沒(méi)有具體使用并沒(méi)有這方面經(jīng)驗(yàn)的話(huà),看這些大概都是云里霧里的
若依分幾個(gè)版本,但都是基于SpringBoot的,這點(diǎn)沒(méi)有問(wèn)題,因?yàn)镾pringBoot是目前Java用的最多的JavaWeb框架了
我目前挑選的是前后端分離版本,若依除此之外還有
- 微服務(wù)版(公司有一定規(guī)模了,有很多臺(tái)服務(wù)器的話(huà)可以用)
- 不分離版(現(xiàn)在基本上都前后端分離了,不分離的基本上沒(méi)人用了吧)
從側(cè)邊欄講起,先大概有一個(gè)了解
首先若依表面上的有三個(gè)大部分
- 系統(tǒng)管理
- 系統(tǒng)監(jiān)控
- 系統(tǒng)工具
其中系統(tǒng)管理是最核心的部分,包含了用戶(hù),角色,菜單,部門(mén)…,可以說(shuō)是一個(gè)ERP系統(tǒng)了
而這些都是已經(jīng)做好了的,我們使用的話(huà)就不需要自己寫(xiě)登錄,做權(quán)限,菜單這些了,需要根據(jù)自己的業(yè)務(wù)去更改
若依是使用了目前市面上流行的一些開(kāi)源框架。Spring系列,比如做權(quán)限驗(yàn)證,前后端分離版是用的Spring Security…
我使用了的這段時(shí)間,給我的感覺(jué)就是”還行“,對(duì)我來(lái)說(shuō),重要的部分就是將權(quán)限都做好了,我只需要專(zhuān)心寫(xiě)接口就可以了。大體我也講不上來(lái),所以寫(xiě)下這篇文章來(lái)總結(jié)一下。
架構(gòu)
使用了 Java,Mysql,Redis
具體參考官方文檔
項(xiàng)目的下載與導(dǎo)入
我選的前后端分離版,前端使用的vue系列
首先從git上拉項(xiàng)目?;蛘呦螺d壓縮包也行,在官網(wǎng)上進(jìn)入對(duì)應(yīng)的倉(cāng)庫(kù)地址
我這里直接使用 Git 下載了,因?yàn)檫@樣比較快(至于沒(méi)有 Git 的先要去下載 Git)
打開(kāi) Git bash,進(jìn)入到自己新建的文件夾中,使用 git clone
命令從網(wǎng)絡(luò)上將git項(xiàng)目克隆下來(lái)
git clone https://gitee.com/y_project/RuoYi-Vue.git
ps: 至于 git 的地址,在官方源碼的Gitee中點(diǎn)擊克隆就可以獲取到了
下載下來(lái)的目錄結(jié)構(gòu)和倉(cāng)庫(kù)展示的目錄結(jié)構(gòu)是差不多的
有的時(shí)候我們會(huì)給文件夾改名稱(chēng),但是建議如果對(duì)這些不是很熟練的話(huà)最好先不要改。不然就會(huì)和我一樣花一些時(shí)間去補(bǔ)錯(cuò)誤了
其中,ruoyi-ui
是前端項(xiàng)目,這里需要注意一下,前端項(xiàng)目和后端項(xiàng)目不要放到一起,因?yàn)榍岸隧?xiàng)目構(gòu)建的時(shí)候會(huì)生成 node_modules 文件夾,這個(gè)文件夾內(nèi)會(huì)有很多的文件,然后后端導(dǎo)入就會(huì)卡死(我Eclipse導(dǎo)入就卡死了,然后改IDEA,后來(lái)才想到是不是這個(gè)的原因,然后將前端項(xiàng)目移出來(lái)就沒(méi)問(wèn)題了…)
后端導(dǎo)入
首先從后端開(kāi)始,導(dǎo)入是非常簡(jiǎn)單的,如果是IDEA的話(huà),那么直接打開(kāi)這個(gè)項(xiàng)目就可以了,這是一個(gè)Maven多模塊項(xiàng)目。
如果是 Eclipse 的話(huà),使用Maven的方式導(dǎo)入,方法如下
File -> Import -> Maven -> Exists Maven Project,然后 Root Directory 選擇若依的文件夾就好了。
然后等待右下角進(jìn)度條開(kāi)始編譯之類(lèi)的,完成后是這樣的
我現(xiàn)在這個(gè)是Eclipse的Java視圖,在Eclipse的JavaEE視圖或者使用IDEA的話(huà),那么子maven模塊會(huì)在父maven模塊的里面而不是展示為同級(jí)
如果你導(dǎo)入不能成功的話(huà),大概率是網(wǎng)絡(luò)的問(wèn)題或者M(jìn)aven的問(wèn)題,帶著報(bào)錯(cuò)去參考網(wǎng)上解決方案進(jìn)行解決
前端導(dǎo)入
那個(gè) ruoyi-ui 就是前端項(xiàng)目。
如果沒(méi)有 Node 則需要先安裝Node,因?yàn)檫@個(gè)是基于 Vue 的。
在前端這個(gè)地方環(huán)境問(wèn)題可搞了我好久的時(shí)間…
就照著基礎(chǔ)的vue項(xiàng)目一樣,打開(kāi)命令行,進(jìn)入前端項(xiàng)目文件夾,使用 npm install
或者 cnpm install
先安裝需要的依賴(lài)。
npm配置了鏡像的話(huà)可以用,不然就照著網(wǎng)上的先安裝 cnpm。
網(wǎng)絡(luò)沒(méi)問(wèn)題的話(huà),執(zhí)行命令完成后,依賴(lài)安裝完后,一般都會(huì)出現(xiàn)一大堆的Depar…什么的紅色文字的錯(cuò)誤,可以先不用去管
執(zhí)行 npm run dev
先看看能不能跑起來(lái),一般情況下,從官網(wǎng)拉下里的是可以直接跑起來(lái)的。
像我這樣,就跑起來(lái)了,會(huì)自動(dòng)打開(kāi)瀏覽器,打開(kāi)前端地址。
下面的 Proxy error 是我沒(méi)有打開(kāi)后端,訪問(wèn)不到后端的問(wèn)題。
當(dāng)然,我第一次其實(shí)是跑不起來(lái)的,問(wèn)題是沒(méi)有 vue-cli-service,現(xiàn)在能跑起來(lái)是因?yàn)槿职惭b了這么個(gè)東西。
如果你沒(méi)有安裝的話(huà),找到前端項(xiàng)目下的 package.json
,從中找到devDependencies,在里面找到對(duì)應(yīng)的版本
然后使用 npm install 或者 cnpm install 安裝就可以了
例如
cnpm install @vue/cli-service@4.4.6
版本號(hào)也是使用 @
分隔
如果缺少的是其他依賴(lài)也可以使用這樣的方式解決
后端運(yùn)行與配置
首先可以看一下若依官方文檔給的項(xiàng)目結(jié)構(gòu)介紹
主要模塊是 admin,所有的接口都在這個(gè)模塊,包括后面自己寫(xiě)的業(yè)務(wù)接口建議都放到這個(gè)模塊
然后是system與common模塊
system模塊是將增刪改查操作都放到里面了,做了分層,Service(提供給接口的服務(wù)層),Mapper(與數(shù)據(jù)庫(kù)的操作,帶xml),domain(JavaBean)
common模塊比較雜,工具類(lèi)都在這里面,包括:
- Redis工具(直接與Redis操作)
- SpringUtils(可以拿到SpringBoot的Context,getBean之類(lèi)的)
- ServletUtils(使用的ThreadLocal,可以拿到當(dāng)前的請(qǐng)求與響應(yīng),接口參數(shù)之類(lèi)的)
- …
更多的需要自己發(fā)現(xiàn)了
framework模塊是若依自己編寫(xiě)的包裝(框架),這部分讓我印象最深的就是權(quán)限認(rèn)證了#-_-#,需求是做第三方登錄,但要自定義登陸的話(huà)。卡了我一天多時(shí)間,主要原因是因?yàn)槲覜](méi)接觸過(guò)Spring Security,關(guān)于有做第三方登陸需求的,這部分我會(huì)在這篇文章中將經(jīng)驗(yàn)寫(xiě)出來(lái)。
還有幾個(gè)模塊,目前我的需求基本上不需要?jiǎng)舆@幾部分,ruoyi-generator 這個(gè)代碼生成,可以根據(jù)需要去修改配置(yml)
配置
都是SpringBoot項(xiàng)目,首先進(jìn)入 admin 模塊,找到 application.yml,進(jìn)入,根據(jù)自己的需要進(jìn)行修改。
比較需要注意的地方是
- ruoyi:profile(上傳文件保存的地址)
- spring:redis:(Redis的配置)
然后進(jìn)入 application-druid.yml,這個(gè)是數(shù)據(jù)庫(kù)的配置,其中要配置數(shù)據(jù)庫(kù)的密碼,數(shù)據(jù)庫(kù)名稱(chēng)等看注釋操作就行
在父模塊文件夾中(RuoYi-Vue),有個(gè)sql文件夾,里面有兩個(gè)sql,需要新建一個(gè)數(shù)據(jù)庫(kù)進(jìn)入,然后執(zhí)行這兩個(gè)sql
這樣就可以運(yùn)行后端了
運(yùn)行后,啟動(dòng)成功的話(huà)可以在控制臺(tái)看到啟動(dòng)成功的字樣的
這樣,將前面說(shuō)前端也運(yùn)行起來(lái),就可以正常使用了。
還有很多地方可以進(jìn)行配置,但在這里就不過(guò)多進(jìn)行贅述了,熟悉SpringBoot的使用基本上沒(méi)有什么太大壓力。
前端配置
首先可能需要配置的是后端的地址。在 vue.config.js
中
我們可能會(huì)發(fā)現(xiàn),前端請(qǐng)求的后端地址路由前綴帶上了 /dev-api
,這是因?yàn)樽隽硕喹h(huán)境,使用了代理,后端并不是這樣的,所以可以忽略這個(gè)。
其余的就是業(yè)務(wù)的編寫(xiě)了,組件部分都在 Component 文件夾,而頁(yè)面布局在 layou 文件夾
我們自己寫(xiě)的頁(yè)面在放 views 文件夾下。
使用
可以先查閱官方文檔,有很多使用上面都有寫(xiě)
代碼生成
首先需要建立一個(gè)sql表,表名稱(chēng)以在generator模塊的yml配置前綴開(kāi)頭,如果沒(méi)有更改的話(huà)就是 sys_
,可以有多個(gè),使用逗號(hào)分隔
然后在系統(tǒng)工具 - 代碼生成界面中導(dǎo)入表(可視化的,不多贅述了),有編輯預(yù)覽和生成,編輯是設(shè)置生成代碼的參數(shù)之類(lèi)的,覺(jué)得沒(méi)問(wèn)題就生成
生成后的壓縮包里有很多文件(大概好像是9個(gè)),包含了一個(gè)sql(菜單的增刪改查sql語(yǔ)句以及權(quán)限等),后端controller、mapper、xml…前端 api.js、view…照著目錄結(jié)構(gòu)放到對(duì)應(yīng)目錄結(jié)構(gòu)就可以了。
公開(kāi)接口
這部分官網(wǎng)文檔上有,不過(guò)不是很顯眼,我找了半天,在這里記錄下
直接加上 @Anonymous
注解就可以了(前后端分離版),在類(lèi)上加,類(lèi)內(nèi)的所有接口都可訪問(wèn),在接口上加那就單獨(dú)公開(kāi)這個(gè)接口
日志
使用 @Log
注解,可以參考若依里的代碼,有很多地方都用到了
但需要注意的是,必須要有登錄信息,也就是說(shuō)公開(kāi)接口不能使用這個(gè)注解。
例如
@Log(title = "字典數(shù)據(jù)", businessType = BusinessType.EXPORT)
還有一個(gè)是登錄日志,這個(gè)可以在登陸類(lèi)中找到,直接照葫蘆畫(huà)瓢就行了。
國(guó)際化
若依是做了國(guó)際化的,但不多。用的 i18n,在 admin 模塊的 resources 下可以看到 i18n 文件夾,有個(gè)message.properties 文件,其中包含了所有的文字…
使用的話(huà)就是
MessageUtils.message("message.properties中的key")
第三方登錄注冊(cè)
這篇文章記下這里就結(jié)尾吧,因?yàn)槿粢朗鞘褂昧撕芏嗫蚣艿囊粋€(gè)快速開(kāi)發(fā)框架。如果熟悉若依所使用的那些框架,那么上手起來(lái)沒(méi)有什么太大的壓力。
對(duì)于第三方登錄,有一個(gè)特點(diǎn),只會(huì)給你一個(gè)第三方的唯一用戶(hù)標(biāo)識(shí),而在若依中,使用的Spring Security(這個(gè)我沒(méi)學(xué)過(guò),所以這里記錄的可能并不是一個(gè)比較好的方法)。
我的方法如下
第三方登錄,用戶(hù)不存在就注冊(cè)并登錄,存在就直接登錄
注冊(cè)很簡(jiǎn)單,參考若依的注冊(cè)接口 System 模塊的 web.service.SysRegisterService
,但因?yàn)槭堑谌降卿?#xff0c;沒(méi)有賬號(hào)密碼,我的做法是生成一個(gè)隨機(jī)的賬號(hào),與默認(rèn)密碼…因?yàn)檎蘸J畫(huà)瓢,登錄是必須要賬號(hào)和密碼的
下面描述的是整個(gè)驗(yàn)證流程部分
首先查閱參考若依的登錄接口,在 system 模塊中 web.service.SysLoginService
它登陸部分代碼是這樣的
/*** 登錄驗(yàn)證* * @param username 用戶(hù)名* @param password 密碼* @param code 驗(yàn)證碼* @param uuid 唯一標(biāo)識(shí)* @return 結(jié)果*/
public String login(String username, String password, String code, String uuid)
{// 驗(yàn)證碼校驗(yàn)validateCaptcha(username, code, uuid);// 登錄前置校驗(yàn)loginPreCheck(username, password);// 用戶(hù)驗(yàn)證Authentication authentication = null;try{UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);AuthenticationContextHolder.setContext(authenticationToken);// 該方法會(huì)去調(diào)用UserDetailsServiceImpl.loadUserByUsernameauthentication = authenticationManager.authenticate(authenticationToken);}catch (Exception e){if (e instanceof BadCredentialsException){// 記錄登錄日志AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));throw new UserPasswordNotMatchException();}else{AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));throw new ServiceException(e.getMessage());}}finally{AuthenticationContextHolder.clearContext();}AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));LoginUser loginUser = (LoginUser) authentication.getPrincipal();recordLoginInfo(loginUser.getUserId());// 生成tokenreturn tokenService.createToken(loginUser);
}
熟悉 Security 的看起來(lái)是非常簡(jiǎn)單的,核心部分就下面這三行。
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
AuthenticationContextHolder.setContext(authenticationToken);
// 該方法會(huì)去調(diào)用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(authenticationToken);
將賬號(hào)和密碼構(gòu)建一個(gè)UsernamePasswordAuthenticationToken
,然后加入context,最后去調(diào)用驗(yàn)證,這是 Spring Security 的一個(gè)基礎(chǔ)的做法
通過(guò)注釋找到 UserDetailsServiceImpl 類(lèi),就在同一個(gè)包下,核心代碼是這樣的
(這部分我已經(jīng)改過(guò)了,將這個(gè)類(lèi)當(dāng)作驗(yàn)證類(lèi)了。)
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{SysUser user = userService.selectUserByUserName(username);if (StringUtils.isNull(user)){log.info("登錄用戶(hù):{} 不存在.", username);throw new ServiceException("登錄用戶(hù):" + username + " 不存在");}else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())){log.info("登錄用戶(hù):{} 已被刪除.", username);throw new ServiceException("對(duì)不起,您的賬號(hào):" + username + " 已被刪除");}else if (UserStatus.DISABLE.getCode().equals(user.getStatus())){log.info("登錄用戶(hù):{} 已被停用.", username);throw new ServiceException("對(duì)不起,您的賬號(hào):" + username + " 已停用");}Object type = ServletUtils.getRequest().getAttribute("type");if (type != null) {switch ((int) type) {case SecurityConfig.TYPE_OTHER:passwordService.validateOther(user);break;}} else {passwordService.validate(user);}return createLoginUser(user);
}
看起來(lái)就好像是在這驗(yàn)證賬號(hào)密碼,雖然可以這樣,但 Spring Security 定義的并不是這樣的…
查閱 SecurityConfig 類(lèi),這個(gè)是 Spring Security 的配置類(lèi),在System模塊的config下,我們需要在意的是最后一個(gè)函數(shù),
/*** 身份認(rèn)證接口*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception{auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());}
在這里如果沒(méi)學(xué)過(guò) Spring Security 就開(kāi)始懵逼起來(lái)了,所以我先去學(xué)習(xí)了Spring Security,流程還是很簡(jiǎn)單,反正就是在這里設(shè)置的 UserDetailsService
因?yàn)槭堑谌降卿?#xff0c;用戶(hù)不需要輸入賬號(hào)密碼,那么我拿到的密碼就是加密后的密碼,這樣就和普通登錄不一樣了,就會(huì)導(dǎo)致認(rèn)證不通過(guò)
經(jīng)過(guò) debug 后發(fā)現(xiàn),首先走的是 AuthenticationManagerBuilder,這個(gè)不用管,只要知道這個(gè)里面有 ProviderManager 就行了,ProviderManager 是個(gè)管理器,具體的我也不記得了,它里面有AuthenticationProvider列表,而AuthenticationProvider這個(gè)東西就是需要解決掉的東西
private List<AuthenticationProvider> providers = Collections.emptyList();
Spring Security 默認(rèn)使用的是 DaoAuthenticationProvider
,跟著debug可以看到
需要注意的就兩個(gè)函數(shù),一個(gè)additionalAuthenticationChecks,一個(gè)retrieveUser
@Override@SuppressWarnings("deprecation")protected void additionalAuthenticationChecks(UserDetails userDetails,UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {if (authentication.getCredentials() == null) {this.logger.debug("Failed to authenticate since no credentials provided");throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));}String presentedPassword = authentication.getCredentials().toString();if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {this.logger.debug("Failed to authenticate since password does not match stored value");throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));}}@Overrideprotected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)throws AuthenticationException {prepareTimingAttackProtection();try {UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);if (loadedUser == null) {throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");}return loadedUser;}catch (UsernameNotFoundException ex) {mitigateAgainstTimingAttack(authentication);throw ex;}catch (InternalAuthenticationServiceException ex) {throw ex;}catch (Exception ex) {throw new InternalAuthenticationServiceException(ex.getMessage(), ex);}}
首先執(zhí)行的是 retrieveUser 函數(shù),這個(gè)函數(shù)會(huì)去調(diào)用若依的 UserDetailsServiceImpl 的 loadUserByUsername 函數(shù)
執(zhí)行完后,會(huì)執(zhí)行 additionalAuthenticationChecks 函數(shù),這個(gè)函數(shù)進(jìn)行賬號(hào)密碼驗(yàn)證,而若依是在 UserDetailsServiceImpl 的 loadUserByUsername 驗(yàn)證的,驗(yàn)證完后還會(huì)在驗(yàn)證一遍,因?yàn)橘~號(hào)密碼的方式相同,所以不會(huì)有什么問(wèn)題,但對(duì)我來(lái)說(shuō),傳遞的密碼是加密的,所以不需要函數(shù)內(nèi)進(jìn)行加密,于是就要干掉這個(gè)類(lèi),在網(wǎng)上找了很久都找不到辦法,就只能自己慢慢嘗試了,這里直接寫(xiě)結(jié)果了
首先新建一個(gè)類(lèi),繼承 DaoAuthenticationProvider 類(lèi),然后覆蓋 additionalAuthenticationChecks 函數(shù),在這個(gè)函數(shù)內(nèi)做自己的操作。
然后還要覆蓋一個(gè)函數(shù) supports,這個(gè)是代表支持不支持當(dāng)前傳遞的 authentication,例如UsernamePasswordAuthenticationToken
我直接返回 true 就行了,不支持的話(huà)那么就不會(huì)被覆蓋
代碼如下
/*** 自定義* 創(chuàng)建時(shí)間 2023年7月29日* @author Shendi*/
public class MyAuthenticationProvider extends DaoAuthenticationProvider {@Overrideprotected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {// 有兩種類(lèi)型Object type = ServletUtils.getRequest().getAttribute("type");if (type != null) {// 已經(jīng)在 UserDetailsService 做了判斷switch ((int) type) {case SecurityConfig.TYPE_OTHER:break;}} else {if (authentication.getCredentials() == null) {this.logger.debug("Failed to authenticate since no credentials provided");throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));}String presentedPassword = authentication.getCredentials().toString();if (!this.getPasswordEncoder().matches(presentedPassword, userDetails.getPassword())) {this.logger.debug("Failed to authenticate since password does not match stored value");throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));}}}/** 是否支持指定類(lèi)型的 authentication */public boolean supports(Class<?> authentication) {
// return (MyAuthenticationProvider.class.isAssignableFrom(authentication));return true;}}
然后就是在 SecurityConfig 中配置了,直接上代碼
@Bean
public MyAuthenticationProvider myAuP() { MyAuthenticationProvider myAuP = new MyAuthenticationProvider(); myAuP.setUserDetailsService(userDetailsService); myAuP.setPasswordEncoder(bCryptPasswordEncoder()); return myAuP;
}/*** 身份認(rèn)證接口*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{auth.authenticationProvider(myAuP());
// auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
這樣就ok了.
END