4spring-security5整合jwt做登錄迫横、權(quán)限驗證番舆,全網(wǎng)最全!7狻恨狈!可用

github源碼:

https://github.com/gyb123456/spring-security5-jwt,最煩那些寫文檔只截圖一半還不給源碼的人呛讲,要不你就截全圖禾怠,要不就給源碼!

前言:

需要研究spring-security和jwt技術(shù)圣蝎,搞了幾天刃宵,現(xiàn)把成果記錄下

環(huán)境

Springboot:2.1.3.RELEASE
spring-security:5.1.4.RELEASE
前后端分離
所需依賴3個衡瓶,具體pom見源碼

 <!--spring-security-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!--jwt-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
spring-security原理

從網(wǎng)上的各種不同方法綜合一下形成了這一套完整框架徘公,源碼里每個類各司其職,很清晰知道是干什么的哮针,現(xiàn)在講一下spring-security原理及工作流程


圖片.png
圖片中各個類的作用:

1 JwtUser類:實現(xiàn)Springsecurity的UserDetails類关面,此類必須有三個屬性
private String username;
private String password;
//權(quán)限,類如ROLE_ADMIN
private Collection<? extends GrantedAuthority> authorities;
2 JwtUtils:jwt工具類
3 MD5Util:密碼加密工具類
4 MyAccessDeniedHandler:實現(xiàn)Springsecurity的AccessDeniedHandler十厢,Spring security權(quán)限不足處理類
5 MyAuthenticationException:實現(xiàn)Springsecurity的AuthenticationEntryPoint等太,Spring security其他異常處理類,比如請求路徑不存在等
6 MyAuthenticationFailHandler: 實現(xiàn)Springsecurity的AuthenticationFailureHandler,Spring security登錄失敗處理類
7 MyAuthenticationSuccessHandler:實現(xiàn)Springsecurity的AuthenticationSuccessHandler蛮放,Spring security登錄成功處理類
8 MyJwtTokenFilter: 繼承Springsecurity的OncePerRequestFilter缩抡,token 過濾器,在這里解析token包颁,拿到該用戶角色瞻想,設(shè)置到springsecurity的上下文環(huán)境中压真,讓springsecurity自動判斷權(quán)限
9 MyUserDetailsService:實現(xiàn)Springsecurity的UserDetailsService,根據(jù)用戶名獲取數(shù)據(jù)庫該用戶信息蘑险,spring security在登錄時自動調(diào)用
10 WebSecurityConfig: Spring security的總配置類滴肿,配置密碼驗證規(guī)則、攔截的url佃迄、登錄接口地址泼差、登錄成功與失敗后的處理器、各種異常處理器

總結(jié):

spring-security工作流程就是

1自動識別登錄接口路徑(你配置的)呵俏,自動進(jìn)入賬戶密碼判斷方法堆缘,判斷規(guī)則可自定義,密碼驗證通過后會進(jìn)入spring security提供的MyAuthenticationSuccessHandler類柴信,在這里重寫方法套啤,用HttpServletResponse自定義返回給前端內(nèi)容,可以返回接口也可以返回html随常,隨你潜沦,我這里返回jwt。驗證失敗同理绪氛。
這里說下 Spring security的賬戶密碼判斷邏輯唆鸡,WebSecurityConfig繼承WebSecurityConfigurerAdapter,注入configureAuthentication方法枣察,重寫matches方法自定義密碼驗證規(guī)則争占,返回boolean

@Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                // 設(shè)置UserDetailsService 獲取user對象
                .userDetailsService(this.userDetailsService)
                // 自定義密碼驗證方法
                .passwordEncoder(new PasswordEncoder() {
                    //這個方法沒用
                    @Override
                    public String encode(CharSequence charSequence) {
                        return "";
                    }

                    //自定義密碼驗證方法,charSequence:用戶輸入的密碼,s:我們查出來的數(shù)據(jù)庫密碼
                    @Override
                    public boolean matches(CharSequence charSequence, String s) {
                        String pass = MD5Util.string2MD5(charSequence.toString());
                        System.out.println("用戶輸入密碼:" + charSequence + "與數(shù)據(jù)庫相同序目?" + s.equals(pass));
                        return s.equals(pass);
                    }
                });

    }

2登錄成功后臂痕,前端攜帶jwt的token來訪問接口,首先會進(jìn)入我們配置的MyJwtTokenFilter 類繼承自O(shè)ncePerRequestFilter猿涨,這個OncePerRequestFilter就厲害了握童,可以說是所有filter的基類,所以最先執(zhí)行叛赚,在這里我們寫驗證jwt的邏輯澡绩,驗證通過后要告訴springsecurity,我們獲取到的用戶的權(quán)限俺附,并把權(quán)限設(shè)置到springsecurity的上下文環(huán)境中肥卡,讓它來給我們做權(quán)限的判斷,這點最重要J铝汀2郊!!是springsecurity和jwt的整合紐帶氛琢,主要代碼如下:

if(JwtUtils.isTokenExpired(Claims)){//token過期
                System.out.println("token過期" + authToken);
            }else{
                System.out.println("token沒過期只嚣,放行" + authToken);
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(UserDetails, null, UserDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                logger.info(String.format("Authenticated userDetail %s, setting security context", username));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }

3springsecurity自動驗證權(quán)限后,如果權(quán)限不足艺沼,會進(jìn)入到我們配置的權(quán)限不足捕獲異常類MyAccessDeniedHandler册舞,其他錯誤的話進(jìn)入另一個異常捕獲類MyAuthenticationException,都可以自定義返回值

如何使用

具體見源碼的-- 說明.txt
本項目是Spring security5+Jwt的基礎(chǔ)實例
功能:
1:驗證用戶登錄賬號密碼是否正確障般,登錄地址可以自定義配置调鲸,密碼驗證規(guī)則也是自定義,我這里只要是123456就行挽荡,驗證成功與失敗分別有不同的類來處理藐石,登錄成功后生成JWT返回
測試方法:http://localhost:8080/user/login?username=adm&password=123456
2:配置攔截除了"/test/**"以外的所有請求,登錄地址配置好以后Spring security會自動設(shè)置為不攔截
3:配置了各種攔截器定拟,具體看代碼
使用方法
1登錄獲取jwt token(在Response Header里)于微,POST http://localhost:8080/user/login?username=adm&password=123456
2根據(jù)token 調(diào)用ROLE_ADMIN權(quán)限接口, GET http://localhost:8080/role/aaa ,返回權(quán)限不足青自,,MyUserDetailsService默認(rèn)給用戶加了ROLE_USER權(quán)限
根據(jù)token 調(diào)用無權(quán)限注解的接口, GET http://localhost:8080/role/bbb 株依,返回正常結(jié)果
根據(jù)token 調(diào)用ROLE_USER權(quán)限接口, GET http://localhost:8080/role/ccc ,返回正常結(jié)果
3調(diào)用不存在的接口延窜,返回捕獲異常http://localhost:8080/tessssst/error

歡迎大家討論點贊??

附:

JWT通用類 https://blog.csdn.net/qq_37636695/article/details/79265711

跨域問題恋腕,postman能拿到值,前端頁面拿不到
1//解決spring security 跨域問題
https://blog.csdn.net/qq_35494808/article/details/82998135
2//解決X-Frame-Options: DENY問題逆瑞,jwt過期時荠藤,自定義返回值時,前端拿不到返回值获高,postman可以看到有的
在configure(HttpSecurity httpSecurity)里加上
.and().headers().frameOptions().disable();
3 在異常處理類的HttpServletResponse里加Header

public static void httpHandle(int stats ,HttpServletRequest httpServletRequest, HttpServletResponse response, String str) throws
            IOException {
        /**
         * 注意這里加上跨域的配置
         */
        response.setHeader("Access-Control-Allow-Origin",httpServletRequest.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");

        response.setStatus(stats);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter printWriter = response.getWriter();
        response.getWriter().write(str);
        printWriter.flush();
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哈肖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子念秧,更是在濱河造成了極大的恐慌淤井,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件出爹,死亡現(xiàn)場離奇詭異庄吼,居然都是意外死亡缎除,警方通過查閱死者的電腦和手機(jī)严就,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來器罐,“玉大人梢为,你說我怎么就攤上這事。” “怎么了铸董?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵祟印,是天一觀的道長。 經(jīng)常有香客問我粟害,道長蕴忆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任悲幅,我火速辦了婚禮套鹅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘汰具。我一直安慰自己卓鹿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布留荔。 她就那樣靜靜地躺著吟孙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪聚蝶。 梳的紋絲不亂的頭發(fā)上杰妓,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機(jī)與錄音碘勉,去河邊找鬼稚失。 笑死,一個胖子當(dāng)著我的面吹牛恰聘,可吹牛的內(nèi)容都是我干的句各。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼晴叨,長吁一口氣:“原來是場噩夢啊……” “哼凿宾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兼蕊,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤初厚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后孙技,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體产禾,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年牵啦,在試婚紗的時候發(fā)現(xiàn)自己被綠了亚情。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡哈雏,死狀恐怖楞件,靈堂內(nèi)的尸體忽然破棺而出衫生,到底是詐尸還是另有隱情,我是刑警寧澤土浸,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布罪针,位于F島的核電站,受9級特大地震影響黄伊,放射性物質(zhì)發(fā)生泄漏泪酱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一还最、第九天 我趴在偏房一處隱蔽的房頂上張望西篓。 院中可真熱鬧,春花似錦憋活、人聲如沸岂津。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吮成。三九已至,卻和暖如春辜梳,著一層夾襖步出監(jiān)牢的瞬間粱甫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工作瞄, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留茶宵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓宗挥,卻偏偏與公主長得像乌庶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子契耿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354