搜尋

搜尋結果

購物資訊 ~ 瑞士高端Stem Premier de GLYCEL幹細胞VII複活系列
美容
蘇蘇・2015-01-23

現今科技發達,護膚已經不止局限於金箔、天然、礦物粉或中藥了,近來最多人談輪的就是幹細胞護膚。 記得很多年前,大家一說起利用幹細胞護膚,會倒抽一口涼氣,皆因當年這類型護膚品非常仰貴,買一瓶動不動都要一萬數千元,我們這些普通人家根本消費不起,只有看的份兒 不過隨著科技的進步,幹細胞系列越來越普及,很多品牌也紛紛開發研究,從而價錢已經回落到可接受水平,所以受惠的美眉就越來越多選擇了。 其中來自瑞士著名品牌 GLYCEL,以突破性瑞士抗老高端科技,嶄新研發出「Stem Premier de GLYCEL 幹細胞Ⅶ複活系列」,推出市場首個結合7大高效植物幹細胞,包括:蕃茄幹細胞、雙花扁豆幹細胞、覆盆子幹細胞、紅桑莓幹細胞、咖啡豆幹細胞、仙人掌幹細胞、嫩膚生物三胜肽,發揮7重抗衰老功效,啟動肌膚細胞複活再生作用,從細胞核心出發,解決肌膚老化跡象,由抑制、修復到複活再生,讓肌膚重現彈滑柔軟。 先來說包裝,真是極緻華麗,讓人目不瑕給、愛不釋手 GLYCEL 幹細胞VII 複活再生精華 HK$1,58030ml 蘊含7種幹細胞精華及強效抗皺成分,全面抗氧,防禦紫外線及游離基侵害,預防肌膚衰老,同時促進細胞代謝,為細胞補充大量養分,修護受損老化細胞,深層滋潤,有助減淡皺紋、幼紋及表情紋,用後肌膚水盈富彈性,更紅潤光澤。 吸管設計,份量易於控制,使用過程更乾淨衛生,精華易於被肌膚吸收,用後感覺柔軟。 GLYCEL 幹細胞VII 複活修護晚霜 HK$1,68050g 性質溫和,有助舒緩及鎮靜肌膚,改善泛紅問題。此晚霜亦能增強骨膠原及彈力蛋白,有助減淡紋理及改善鬆弛肌膚。迅速注水補濕作用,能鎖緊水分於肌膚底層,肌膚變得水嫩細緻。 千多元就可以買一瓶來自瑞士著名品牌的幹細胞護膚產品,蘇蘇想不到什麼理由拒絕放它們在購物清單內呢

中世紀的海盜古城 法國濱海小鎮聖馬洛
走遍世界
行走世界記錄・2019-08-20

美麗的法國濱海小鎮 位於法國西北邊的布列塔尼 Bretagne,有一座面向英倫海峽的美麗濱海小鎮,與英國隔海遙遠相望。 可麗餅起源地 大家可能對布列塔尼 Bretagne並不熟識,但一說到可麗餅Crepes,即時跟起源地布列塔尼連繫起來。 與英國一海之隔 聖馬洛 法語 Saint Malo位處諾曼第邊緣,與英國一海相隔,中世紀時聖馬洛是法國重要的軍事港口,防禦英國侵略的國防要塞。 聖馬洛 從巴黎乘TGV直達車來到聖馬洛只需2.5小時,如果選擇轉車的話,則要3小時才可到達。 火車站位於古城外,出站後沿海旁步行15分鐘便到達古城入口。 完好保存的中世紀古城 高高的城牆把聖馬洛分為新城與古城區,城內城外的風光截然不同,穿過城門的一刻,彷彿穿越時空,返回數百年前的中世紀。 進入古城,往上爬到古老的城牆上,往外看到英倫海峽,隔海與英國遙遠相望,往內則看到一排排的古老房子。 充滿中世紀風貌的聖馬洛古城,高低起伏的街道,堅固的石圍牆內的街道和房子也是石頭建築的,漫步其中彷如置身中世紀的時代。 沿古老石街小巷,走著走著,會碰到海盜嗎? 中世紀海盜之城 聖馬洛是著名的海盜之城,專門在海上搶劫英國的商船。為何被稱為著名,而不是臭名昭著呢 歷史上有一位人物,英國將他視為頭號海上通緝犯,但在法國則被視為海賊王 法文:Roi des Corsaires,英文:King of Corsairs。他被拿破崙選中為海上指揮官,因為優異表現獲得法國榮譽軍團勳章司令勳位。 中世紀海賊王 羅伯特修考夫 羅伯特修考夫Robert Surcouf 一生總共劫掠47艘英國商船,賺取了億萬財富,被稱為海賊王,在聖馬洛找到記載他事跡的書本,看起來很有當代英雄的感覺。 羅伯特修考夫在他13歲時逃離學校,獨自駕駛一艘小船出海,遇上了暴風雨被救上岸。兩年後,他自願投身印度商船前往東方,回到家鄉後,法國大革命已爆發,換成了拿破崙執政大權。在多年的海上歷練下,成就個人勇氣與智慧,他受命率領著聖馬洛的海船抵禦英國艦隊的侵擾,劫掠英國船隻,寫下海上生涯的傳奇。 聖文森城門 從聖文森城門進入聖馬洛古城,城門上有聖母與主聖穌像,像是向上主祈禱保祐古城內的居民安全,免受外敵侵擾。 城內風光,有餐廳商店,也有酒店旅館,可以選擇在古城內住上一晚,感受海賊王之城的當代輝煌。 而我則選擇在入城的海旁主幹路上的宜必思,原因很簡單,方便到火車站及古城,重要的是酒店面對大海,好運的話能夠以便宜的價格訂上海景房間。 房間的設計很簡單,重點是看到大海,酒店的餐廳的性價比也高,雖然古城內有很多餐廳,但最後還是選擇待在餐廳把早午餐也搞定。 必嚐藍青口 坐在餐廳的角落,望對無際大海,自在休閒地啖上一口啤酒。聖馬洛和聖米歇爾山盛產藍青口Moule,小小的貝殼內的藍青口卻出奇地肥美鮮甜,一試便愛上了。 訂房小貼士:聖馬洛有兩間宜必思的,緊記近海的是一間是聖馬洛海濱宜必思酒店 Hotel ibis Saint Malo Plage,另一間是聖馬洛宜必思尚品酒店 Ibis Styles Saint Malo Port,設計時尚,但不是面對大海的。 著名潮汐差 沿著海旁的主幹馬路步行往古城,看到沙灘上弄潮的人們,旁邊圍著一條條的木欄,起初感到有點不明白,後來參觀完古城,回程返回酒店時,即時仿然大悟。 在太陽和月亮的作用下,聖馬洛一天會有兩次潮漲和潮退,潮汐之差高達56米,是世界上數一數二的潮汐差。 站在海旁的道路上,看著太陽西下,沙灘漸漸被海水完全覆蓋,首次看到潮汐景象,嘆為觀止。 夕陽西下 汪洋一片 大自然的力量 晚上的大海,當早上起來,打開窗戶,看到海水已退,變回一個沙灘,大自然的力量,真不可少觀。 從巴黎到聖馬洛的交通方式 地鐵線: 4、6、12 、13 Montparnasse Bienvenue站 蒙帕那斯火車站 Gare Montparnasse 3小時到達聖馬洛 St. Malo 行程建議 聖馬洛和聖米歇爾山之間有巴士往來,可考慮把兩個旅遊點連在一起規劃,決定先到聖馬洛還是聖米歇爾山,利用Dol De Bretagne火車站作中轉,往還兩個景點。 出站後在右手邊有巴士站,由於班次很少,預先查時刻表趕上當天的班次便成。 巴士直達聖米歇爾山的停車點,再搭接駁車或馬車進入山城,一次過把遊法國西北邊的布列塔尼的兩個著名景點。 更多精彩文章在 行走世界記錄

年年難過年年過, 犯太歲的你還好嗎?
宗教玄學
熊神進・2022-05-05

#本命年佩帶什麼# 有一位女生, 她早上來電告訴我ldquo;我已經經歷了三次本命年, 今次是我最糟糕的一年rdquo;, 她說。 她的丈夫出軌, 出軌男帶著情妖在主臥的床上鬼混。那情妖是強者, 她把自己金色的長頭髮故意留在枕頭下。 犯太歲, 本命年真的倒楣?筆者不是完全同意。 三世書說, 人的運氣是從母親陰陽受精開始, 並不是出生的時候才開始計算, 因此政府註冊的玄學家開命盤時候, 他她們要取女生的受孕資料, 雖然有點尷尬, 但也是無奈。 本命年是十二生肖中的一個, 而犯太歲就可能是二至五個不等, 年年不同, 有輕有重, 姑勿論你犯了哪一種太歲, 我們在未來下半年都要注意幾件事: 在自己生日農曆那天, 第一口吞進肚子的, 是素。 貼身衣服是紅色。 上半年拜太歲, 下半年拜冤親債主可以找師傅代拜。 盂蘭節晚上8時後不洗頭。 公幹旅行不要租住有狀況的X酒店, 身邊放一件「佛號聖牌」。 既然都知道自己是本命年, 為什麼不在包包裡擺放一件「2022年虎猴蛇豬生肖吉祥物女生朱砂六字真言桶」? 《救風塵》第一折說過「恁時節,船到江心補漏遲,煩惱怨他誰。」我們常常說ldquo;有早知, 沒乞兒rdquo;也說 ldquo;能知三日事, 富貴萬千年rdquo;, 這是對的。古時候我們找師傅算命占卜是需要銀兩, 現代科技發達, 各地師傅會透過互聯網把相關本命年資訊發佈, 我們只要關注一下, 點擊一下, 收藏一下, 下次就可更快地收到師傅的善知識。 本命年是需要注意,大病是從小病開始,病向淺中醫,不要再任性。 公共微信 macaumasterxiong 私人微信 macaumickey

樂壇長青組合溫拿將於2017年1月21日降臨澳門威尼斯人
音樂聯合國
LifeMag Editor・2016-12-29

「香港男子偶像樂隊」鼻祖溫拿樂隊將於2017年1月21日在澳門威尼斯人reg;的金光綜藝館舉行《溫拿 Never Say Goodbye演唱會2017-澳門站》。門票於12月29日(星期四)起透過各大金光票務售票處公開發售。 溫拿於70年代中組成,一直為不同年齡的歌迷帶來歡樂,亦憑藉他們無限的創作力、活力以及正能量,繼續吸引更多新的歌迷。 溫拿是香港最受歡迎樂隊組合之一,除了成功涉足影視等多個領域,成員們的個人事業亦發展得非常成功。他們不朽的人氣,讓溫拿五虎每次重聚演出的門票皆全部搶購一空。 才華滿溢的溫拿樂隊每次在演唱會上平均表演50首作品,包括翻唱英文經典金曲,演唱《慶幸一起》、《溫拿精神》等多首新舊大熱歌曲。今次演唱會的主題《溫拿精神》亦本著「當然係一直陪住樂迷成長,間中遇到逆境一齊面對」、「永遠帶無限嘅歡樂俾樂迷」等精神陪伴一眾歌迷。 演唱會門票詳情: 票價 澳門幣 港幣1,480元 VIP區 澳門幣 港幣 1,180元 A 區 澳門幣 港幣 880元 B 區 澳門幣 港幣 580元 C 區 澳門幣 港幣 280元 D 區 船票套票 觀眾可另加澳門幣港幣108元購買包括金光飛航往返港澳雙程船票的套票 售票處 金光票務 網上訂購:www.cotaiticketing.com 售票處: o 澳門巴黎人 ndash; 一樓正門大堂售票處及五樓巴黎人劇場售票處 o 澳門威尼斯人 ndash; 金光綜藝館及酒店正門大堂售票處 o 澳門四季酒店 ndash; 百利宮trade;售票處 o 澳門金沙reg; ndash; 一樓售票處 o 金沙城中心 ndash; 喜來登酒店正門及假日酒店正門售票處 電話訂購: o 澳門熱線:853 2882 8818 o 香港熱線:852 6333 6660 o 中國內地免費熱線:4001 206 618 澳門廣星傳訊 網上訂購:www.macauticket.com 門市據點資料請瀏覽:www.macauticket.comTicketWebServiceStations.aspx 電話訂購:853 2855 5555

出走三亞。三亞理文索菲特度假酒店。2016法國音樂節最後一站
音樂聯合國
蘇蘇・2016-07-31

法國是一個蘇蘇很想旅遊的地方,而聽音樂是蘇蘇的嗜好之一,相信暫時還未有機會出走法國,那就先參與由世界酒店品牌索菲特於中國舉行的法國音樂節吧,先謝謝雅高集團和三亞理文索菲特度假酒店邀請。 今年世界音樂日的主題是ldquo;音樂無處不在,參與共享歡快rdquo;。索菲特酒店已經連續第七年舉辦音樂節 Fete de la Musique 活動,這是一個起源於法國的音樂活動,自1982年創辦以來,每年夏季期間都會在歐洲舉行。 一貫以來,索菲特酒店擁有四大品牌支柱 mdash; 設計、文化、美食和康樂,而促進法國文化的傳播交流正是其品牌核心的使命之一。每家索菲特酒店都將圍繞今年的主題打造自己的音樂節活動,而大中華區的音樂節 lt;Fly Like a Song 音樂會gt; 於6月18日在澳門十六浦索菲特酒店首站啟動、並先後於6月21日在廣州聖豐索菲特大酒店以及6月24日在三亞理文索菲特度假酒店舉行。 因需要上班的關係,蘇蘇只能抽出時間出席於三亞理文索菲特度假酒店舉行的音樂節最後一站演出。 是次音樂節邀請了極富盛名的法國歌手兼吉他手 Henry Padovani 演出,Padovani 也是英國搖滾組合 The Police 成員和聯合創始人。在其漫長的音樂事業生涯中,他曾嘗試過各種音樂風格和相關領域,而其最新創作的ldquo;Fly Like aSongrdquo;音樂概念,收錄了其最喜愛的曲目,從夢幻藍調到經典搖滾,無不展示其最純粹簡單的音樂魅力。 有關三亞理文索菲特度假酒店的美,蘇蘇會寫另一篇分享文詳述,敬請期待。 人到了三亞,一切準備就緒,開開心心去會場。 一班新知舊友一起參與盛事,真的很開心 現場這個酒店御用的歌唱組合 Latinos Hearts 來自拉丁美洲的烏拉圭,除了結他和豎琴彈得好外,唱歌的女孩子聲音也很悅耳,而且他們很擅長搞氣氛。 會場佈置相當有水準,找到位置後就靜心等待節目的開始,坐在蘇蘇附近和前面的就是一眾香港藝人,酒店方面真的很有面子,很多藝人給面子出席。 Henry Padovani 出場了,他以英法雙語傾情演繹他最愛的古典搖滾樂曲,觀眾都聽得如痴如醉。 除了如痴如醉的還有如真如假的,當賓客們沉浸在Henry Padovani的迷人聲線中,神秘嘉賓的即興登台又將晚會帶入新的高潮,來自香港殿堂級歌手、溫拿樂隊成員ndash; 譚詠麟、彭健新、陳友,一同登台為賓客們近距離地呈獻了自70年代起便經久不衰的多首名曲,大家都興奮極了。 全場觀眾都情緒高漲,有不少觀眾衝到台前拍照,幸好他們也比較收歛,只是拍照而已,而且酒店保安措施也很好,大家可以近距離聽校長唱歌,又是如痴如醉。 音樂會在一片美妙歌聲、音樂聲、歡呼聲和掌聲中徐徐落幕了。 台下的Henry十分親切沒架子。 溫拿三虎也是一樣,譚校長、彭健新和陳友真的很親切,每當用膳時間我們都會在酒店的餐廳碰面,合照是少不免的吧。 蘇蘇有幸參加了今年由雅高酒店集團索菲特酒店舉辦這法國音樂節活動,讓我又進一步擴闊了眼界,謝謝 更多各地吃喝玩樂、美容、潮流、旅遊、演藝、文化或購物資訊、心情話語文章等,繼續以一文多發形式發放於中、港、澳三地多個高人氣時尚生活網站的專欄內,詳情請點擊蘇蘇的 新浪微博 『蘇蘇的部落』httpwww.weibo.comsusannaklprofile Facebook httpswww.facebook.comsososusanna Instagram httpinstagram.comsososusanna 時尚生活專欄 ELLE HK 澳門人氣資訊網站CTM ELLE CHINA 中國瑞麗時尚網 搜狐新聞網 手機Apps 聯絡及邀約 susannakL88@yahoo.com.hk

澳門百老匯推中秋歡慶活動
節慶盛事
LifeMag Editor・2016-09-13

澳門首個集美食娛樂、街頭表演、及無限歡樂於一身的娛樂新地標「澳門百老匯trade;」為迎接中秋佳節的來臨,將舉行一連串的精彩活動以及娛樂表演,敬邀賓客共用月滿中秋嘉年華盛會。 由9月1日開始,百老匯美食街將張燈結綵,提供多種中秋歡慶活動,為賓客帶來極具澳門本土風情的精彩體驗。在今年中秋佳節,不論是澳門本地居民或是外地遊客都可完全沉醉在「澳門百老匯」月滿團圓的氣氛之中,「澳門百老匯」亦將舉辦一連串遊戲以及娛樂表演,賓客更有機會可贏取多種豐厚獎品。 一年一度的「澳門百老匯」精彩花燈巡遊是中秋盛會的熱門活動之一,由9月10日的週末以及中秋三日節慶期間,七彩繽紛的金月花燈巡遊將點亮整條百老匯大街,熱鬧非凡。為期五天的巡遊在出發前更會向現場賓客免費派發花燈,力求為賓客打造一個美妙難忘的中秋佳節。除月滿花燈巡遊之外,在9月15日與16日晚9時後,極具現場震撼力的百老匯搖滾秀將帶領賓客感受今年中秋ldquo;圓月搖滾秀rdquo;的節日氛圍,同時也為年輕族群提供充滿活力的狂歡體驗。賓客更可在此期間參加中秋燈謎遊戲,如能在指定時間內解答,即有機會贏取精美「百老匯」紀念品。 今年七夕佳節正式對公眾開放的澳門全新地標mdash;mdash;「情系百老匯」,坐落于「福龍葡國餐」對面,眺望著橫琴新區,在月圓人團圓的浪漫節日氣氛裡,愛侶亦或家人來至此用鎖頭鎖住長久,在皎潔月光的見證下許諾「愛鎖永恆,情約今生」的美麗誓言。 月滿中秋嘉年華期間,遊客更可蒞臨「澳門百老匯」旗下11間餐飲食食府,品嘗12款令人流連忘返的鮮蟹菜色,盡享「滋味蟹逅」活動,品嘗指定蟹宴,更可有機會贏取Vespa摩托車及澳門悅榕庄超豪吃喝住宿禮遇。歡樂坊在每日晚餐時分將為賓客帶來「啤一啤 聚一聚」活動,提供9款國際知名品牌手工啤酒以及各式佐酒小吃,同時配備豐富的互動遊戲以及現場娛樂表演,為賓客帶來一場歡樂的感官盛宴。百老匯美食街亦推出免費「一轉即賞」活動,賓客可免費參加幸運輪遊戲,便有機會贏取「澳門百老匯」準備的如鮮蟹滋味菜式、餐飲儲值額等豐盛人氣獎品。 「澳門百老匯」中秋盛會活動將舉行至9月17日,各式中秋佈置將會一直持續至9月18日,是賓客遊玩拍照的絕佳之處。有關活動以及獎品詳情,可登入:httpwww.broadwaymacau.com.mo,敬請留意網站公佈獲取更多資訊。

旅行上網沒難度 ~ 我的Pocket WiFi
走遍世界
蘇蘇・2015-01-01

每次在國內或國外公幹或旅行,蘇蘇都一定需要上網,除了可以上載照片去社交網站跟大家即時分享當地美食、美景、新奇事物、甚至酒店環境之外,還有可以利用手機地圖或導航功能尋找目的地,對蘇蘇來說更重要的是可以隨時跟澳門的家人緊密聯系,因為我家大小姐和大少爺還是需要我的協助,所以每次出外一到達目的地蘇蘇第一時間不是去找車子,而是去買當地可以上網的電話卡 不過從去年開始,蘇蘇每次出外就不用那麼頻樸了,當車子進入目的地境內或飛機降落之後,蘇蘇就可以優游自在的從口袋裡拿出一隻蛋,不是吃的那種蛋,也不是小孩子玩的扭蛋,更不是暖蛋,而是一隻WiFi 蛋,按著它就可以隨時隨地輕鬆流動上網啦。 其實它的正確名字叫 Pocket WiFi,蘇蘇選用的是來自香港易訊數據 esondata 的。 究竟 Pocket WiFi 是甚麼 Pocket WiFi 是一部接收發送流動數據的裝置,只要你的手機,平板電腦抑或手提電腦支援 WiFi 功能,都可接收其 WiFi 訊號就可以輕鬆上網。易訊數據的可同時連接最多五部電話、平板電腦或手提電腦共用。 另外使用 Pocket WiFi 最大的好處就是你的手機仍可保留使用自己的SIM咭,與親友保持聯繫。 用法十分簡單,按著按扭搜尋Wifi 後再輸入密碼就可以了,還是害怕不懂用,每次租用易訊的 WiFi 蛋都會隨機附上使用指南,如果你說連指南都不懂看,那我就幫不到你啦 它體積細小,擕帶方便,用法簡單,充一次電大約可使用68小時,如果中途電源快要用盡時,跟手機一樣接駁外置充電器就可繼續使用啦。 澳門的朋友一定會問,我在澳門,這公司在香港,莫非要我坐船往香港辦租用手續 現在交通運輸和物流那麼方便,怕什麼呢 無論在香港抑或澳門,在網上完成租用手續之後,易訊就會派速遞公司在辦公時間內、你出發之前連同充電插頭送到你手上啦。 近年蘇蘇無論返國內抑或出國公幹旅行,都有它相伴在旁,為我打開了網絡數據方便之門,特別在國內,竟然也可以上facebook, youtube,Yahoo 等網站,所以受到不少明星名人歡迎,如數個朋友一同旅遊時租用成本更低,比買電話卡更方便更便宜。 不過每個地方收費都不同,大家租用前要請先了解清楚收費項目及用量事宜啊,不過一般價錢都不高的,這個易訊數據的 Pocket WiFi 好幫手,經過自己及朋友親身測試,發現上網速度快而穩定,無論在國內、台灣、歐洲、加拿大都很順暢,現在公幹或旅行需要上網,帶這個是常識吧 易訊數據Pocket Wifi 詳情 www.esondata.com

Spring Boot 05 - 為 http json api 加入登入要求
科技新知
MacauYeah・2024-07-02

本節,我們將為之前的http服務,加入認證機制,只有在資料庫現存的用戶可以登入及訪問我們的json api。 下戴模版 慣例,我們用Spring Initializr Maven 下載模版,Dependency主要選擇 Spring Web Spring Boot DevTools Spring Security Controller 跟上節一樣,我們起一個Controller,為簡化測試,我們只做http GET api。 由於本blog對於Source Code的顯示不太友好,有需要看source code的,請到Github查看 srcmainjavaiogithubmacauyeahspringboottutorialspringbootwebapidatacontrollerHomeController.java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMappingquot;apiquot; public class HomeController @GetMappingquot;someRecorduuidquot; public Map readSomeRecord@PathVariable String uuid return Map.ofquot;retquot;, quot;your uuidquot; uuid; 準備我們的test case,但這次我們預期它應該要出現登入失敗的結果。 srctestjavaiogithubmacauyeahspringboottutorialspringbootwebapidatacontrollerHomeControllerTest.java @SpringBootTest @AutoConfigureMockMvc public class HomeControllerTest @Autowired private MockMvc mockMvc; @Test void testNoLogin throws Exception RequestBuilder requestBuilder = MockMvcRequestBuilders.getquot;apisomeRecord1234quot; .contentTypeMediaType.APPLICATION_JSON; this.mockMvc.performrequestBuilder .andExpectMockMvcResultMatchers.status.is4xxClientError .andExpectMockMvcResultMatchers.jsonPathquot;$.retquot;.doesNotExist .andDoMockMvcResultHandlers.print; 在我們執行上述的測試,test case 成功過了。我們的基本設定跟上一節其實沒有多大改動,為何現在http api會回傳狀態 401? 那是因為我們在依賴中加了,Spring Security,它配合了Spring Web,就會自動為所有api加入權限檢測。我們的測試中,沒有任何用戶登入,當然會出現 http 401。為了讓我們可以好好管理誰可以使用api,我們就來設定一定Security。 我們加一個WebSecurityConfig.java,暫時指定所有的訪問路徑都必需有USER權限,並且用 http basic的方式登入。 srcmainjavaiogithubmacauyeahspringboottutorialspringbootwebapidataconfigWebSecurityConfig.java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class WebSecurityConfig @Bean SecurityFilterChain securityFilterChainHttpSecurity http throws Exception http.authorizeHttpRequestsauthorizeHttpRequests gt; authorizeHttpRequests.requestMatchersquot;quot;.hasRolequot;USERquot;; 所有的訪問路徑都必需有USER權限 ; http.httpBasicCustomizer.withDefaults; 使用http basic作為登入認證的方式 return http.build; 上述例子,只是擋了沒有權限的人,我們還需要讓有登入身份的用戶可以成得取限User權限。 我們繼續修改,WebSecurityConfig,加入只在記憶體有效的InMemoryUser import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; public class WebSecurityConfig .. @Bean public PasswordEncoder passwordEncoder return new BCryptPasswordEncoder; 我們的密碼不應該明文儲,比較保險,我們使用BCrypt演算法,為密碼做單向加密。 @Bean public UserDetailsService userDetailsService UserDetails user = User.withUsernamequot;adminquot; .passwordpasswordEncoder.encodequot;passquot; .rolesquot;USERquot;.build; 我們在記憶中體,加入一個測試用的User,它的名字為admin,密碼為pass,權限為User return new InMemoryUserDetailsManageruser; 然後加入新的測試,直接模擬Role。結果是通過的。 srctestjavaiogithubmacauyeahspringboottutorialspringbootwebapidatacontrollerHomeControllerTest.java @Test void testLoginWithRoles throws Exception RequestBuilder requestBuilder = MockMvcRequestBuilders.getquot;apisomeRecord1234quot; .contentTypeMediaType.APPLICATION_JSON.with SecurityMockMvcRequestPostProcessors.userquot;someonequot; .rolesquot;USERquot;, quot;ADMINquot;; 沒有使用密碼,只使用Role this.mockMvc.performrequestBuilder .andExpectMockMvcResultMatchers.status.is2xxSuccessful .andExpectMockMvcResultMatchers.jsonPathquot;$.retquot;.valuequot;your uuid1234quot; .andDoMockMvcResultHandlers.print; 再來一個測試,改用密碼登入,分別輸入錯的和正確的密碼。 @Test void testLoginWithWrongPasswordAndNoRole throws Exception RequestBuilder requestBuilder = MockMvcRequestBuilders.getquot;apisomeRecord1234quot; .headerquot;Authorizationquot;, quot;Basic randompassquot; 輸入錯的密碼,應該回傳http 401 Unauthorized .contentTypeMediaType.APPLICATION_JSON; this.mockMvc.performrequestBuilder .andExpectMockMvcResultMatchers.status.is4xxClientError .andDoMockMvcResultHandlers.print; @Test void testLoginWithPassword throws Exception RequestBuilder requestBuilder = MockMvcRequestBuilders.getquot;apisomeRecord1234quot; .headerquot;Authorizationquot;, quot;Basic YWRtaW46cGFzcw==quot; http basic 就是把 adminpass 轉成base64 .contentTypeMediaType.APPLICATION_JSON; this.mockMvc.performrequestBuilder .andExpectMockMvcResultMatchers.status.is2xxSuccessful .andExpectMockMvcResultMatchers.jsonPathquot;$.retquot;.valuequot;your uuid1234quot; .andDoMockMvcResultHandlers.print; 最後,當然是正確的密碼才能通過。若果大家還是半信半疑,我們可以跑起真的正服務(IDE RUN或mvn springbootrun),然後用curl去試。 curl httplocalhost8080apisomeRecord1234 failed with 401 curl u quot;adminpassquot; httplocalhost8080apisomeRecord1234 successed 使用SQL Database讀取用戶登入資訊 一般而言,我們不可能把所有用戶登資訊打在InMemoryUser中,通常背後有一個資料庫儲存所有的用戶資訊,我們在登入時,讀取它來做對比檢證。 為此,我們在maven中,加入 Spring Data JPA h2 database (或任何你的資料庫,如mysql 、 sql server) 最後一步,我們把InMemoryUser去掉,改為從資料庫讀取。因為原始碼太多,就不全部貼上。最主要的是WebSecurityConfig.java要關掉之前的UserDetailsService,改為提供一個UserServiceImpl類,它會實現UserDetailsService的功能。 @Configuration @EnableWebSecurity public class WebSecurityConfig 把原來的Bean先變成註解,其他不變 @Bean public UserDetailsService userDetailsService UserDetails user = User.withUsernamequot;adminquot; .passwordpasswordEncoder.encodequot;passquot; .rolesquot;USERquot;.build; return new InMemoryUserDetailsManageruser; springboottutorialspringbootwebapidatasrcmainjavaiogithubmacauyeahspringboottutorialspringbootwebapidataconfigUserServiceImpl.java other import import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; @Service public class UserServiceImpl implements UserDetailsService @Autowired PasswordEncoder passwordEncoder; @Autowired UserRepo userRepo; @Override public UserDetails loadUserByUsernameString username throws UsernameNotFoundException 因為我們資料庫沒有資料,為了方便測試密碼的加密,我們在java code上直接插入一筆資料。 UserEntity defaultUser = new UserEntity; defaultUser.setUsernamequot;adminquot;; defaultUser.setPasswordpasswordEncoder.encodequot;passquot;; defaultUser.setRolequot;USERquot;; defaultUser.setUuidUUID.randomUUID.toString; userRepo.savedefaultUser; 上述為測試用插入資料,不應該出現在正式使用環境中。 UserEntity user = userRepo.findOneByUsernameusername .orElseThrow gt; new UsernameNotFoundExceptionusername quot; not foundquot;; 找找資料庫有沒有正在登入的該名使用者username List authorities = List.ofnew SimpleGrantedAuthorityquot;ROLE_quot; user.getRole; LOG.debugquot;got user uuid, username, role from databasequot;, user.getUuid, username, user.getRole; 如果前面的 findOneByUsername 有結果回傳,我們就給它一個ROLE_XXX的權限。 return new Userusername, user.getPassword, authorities; 這裏從沒有檢查過密碼是否有匹配,全部交給Spring Security去做 springboottutorialspringbootwebapidatasrcmainjavaiogithubmacauyeahspringboottutorialspringbootwebapidataentityUserEntity.java springboottutorialspringbootwebapidatasrcmainjavaiogithubmacauyeahspringboottutorialspringbootwebapidatarepoUserRepo.java 上述段落中,筆者省略了UserEntity和UserRepo,它們只是一般的springdatajpa概念,有需要可以經文末的連結查看完全原始碼。最需要注意的,是UserEntity的password欄位,在資料庫中是以加密的方式儲存。我們在配匹登入者與資料庫記錄時,也沒有自行檢驗密碼的需要。我們只是在加密過的密碼回傳給Spring Security,Spring框架會自行把登入者輸入的密碼與加密了的密碼作比較。