日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Stateless State Security第3部分:JWT +社会认证

發布時間:2023/12/3 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Stateless State Security第3部分:JWT +社会认证 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我的Stateless Spring Security系列文章的第三部分也是最后一部分是關于將基于JWT令牌的身份驗證與spring-social-security混合在一起的。 這篇文章直接建立在此基礎上,并且主要集中在已更改的部分上。 想法是使用基于OAuth 2的“使用Facebook登錄”功能來替換基于用戶名/密碼的登錄,但是此后仍使用相同的基于令牌的身份驗證。

登錄流程

客戶端

用戶單擊“使用Facebook登錄”按鈕,該按鈕是指向“ / auth / facebook”的簡單鏈接,SocialAuthenticationFilter注意到缺少其他查詢參數,并觸發了將您的網站用戶重定向到Facebook的重定向。 他們使用用戶名/密碼登錄,然后重定向回“ / auth / facebook”,但這一次指定了“?code =…&state =…”參數。 (如果用戶以前登錄過facebook并設置了cookie,那么facebook甚至會立即重定向回該用戶,并且根本不會向用戶顯示任何facebook屏幕。)有趣的是,您可以按照瀏覽器網絡日志中的說明進行操作。所有操作均使用純HTTP 302重定向完成。 (HTTP響應中的“ Location”標頭用于告訴瀏覽器下一步要去哪里)

服務器端

從facebook重定向到“ / auth / facebook?code =…&state =…”之后,SocialAuthenticationFilter現在可以看到適當的參數,并將觸發兩個服務器調用Facebook。 第一個是獲取已登錄用戶的訪問令牌,第二個是通過使用訪問令牌獲取用戶詳細信息來測試整個過程是否成功。 完成所有這些操作后,就認為用戶已登錄,并且可以使用另一個302重定向(到“ /”)將其重定向回到應用程序的根目錄。

關于Spring社交的一些話

Spring Social是用于處理社交網絡的完整框架,其范圍遠遠超出了單純的登錄方案。 除了不同的社交網絡適配器之外,還有一個名為Spring Social Security的小型集成庫,該庫以與Spring Security更好地集成的方式實現了社交身份驗證用例。 它帶有一個映射到“ / auth”的SocialAuthenticationFilter,這就是我們將要使用的。

因此,設置社交身份驗證需要使用簡潔的Spring Social Security庫配置Spring Social本身以及Spring Security 。

Spring社交

配置它基本上涉及擴展SocialConfigurerAdapter。 首先,您告訴它要支持哪些社交網絡:

將facebook添加為提供者

@Override public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {cfConfig.addConnectionFactory(new FacebookConnectionFactory(env.getProperty("facebook.appKey"),env.getProperty("facebook.appSecret"))); }

它還需要知道如何獲取當前用戶的用戶ID:

檢索UserId

@Override public UserIdSource getUserIdSource() {//retrieve the UserId from the UserAuthentication in security contextreturn new UserAuthenticationUserIdSource(); }

最后,它需要一個UsersConnectionRepository。 基本上負責用戶及其與社交網絡的連接之間的關系。 Spring Social帶有自己的兩個實現(jdbc或內存中)。 我選擇自己動手,因為我想重用基于Spring Data JPA的UserDetailsS??ervice。

自定義UsersConnectionRepository

@Override public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {SimpleUsersConnectionRepository usersConnectionRepository =new SimpleUsersConnectionRepository(userService, connectionFactoryLocator);// if no local user record exists yet for a facebook's user id// automatically create a User and add it to the databaseusersConnectionRepository.setConnectionSignUp(autoSignUpHandler);return usersConnectionRepository; }

Spring安全

如上一篇博客文章所述,配置它基本上涉及擴展WebSecurityConfigurerAdapter。 除了配置和公開AuthenticationManager和UserDetailsS??ervice之類的常規內容外,它現在還需要配置和插入SocialAuthenticationFilter。 由于SpringSocialConfigurer完成了大部分工作,因此這基本上只涉及很少的代碼。 它可能很簡單:

@Override protected void configure(HttpSecurity http) throws Exception {// apply the configuration from the socialConfigurer // (adds the SocialAuthenticationFilter)http.apply(new SpringSocialConfigurer()); }

考慮到我想插入基于令牌的身份驗證,我自己的succesHandler和userIdSource; 我必須進行一些配置更改:

@Autowired private SocialAuthenticationSuccessHandler successHandler; @Autowired private StatelessAuthenticationFilter jwtFilter; @Autowired private UserIdSource userIdSource;@Override protected void configure(HttpSecurity http) throws Exception {// Set a custom successHandler on the SocialAuthenticationFilter (saf) final SpringSocialConfigurer sc = new SpringSocialConfigurer(); sc.addObjectPostProcessor(new ObjectPostProcessor<...>() {@Overridepublic <...> O postProcess(O saf) {saf.setAuthenticationSuccessHandler(successHandler);return saf;} });http....// add custom authentication filter for stateless JWT based authentication .addFilterBefore(jwtFilter, AbstractPreAuthenticatedProcessingFilter.class)// apply the configuration from the SocialConfigurer .apply(sc.userIdSource(userIdSource)); }

如果您愿意,還可以繼承SpringSocialConfigurer的子類,并為自定義的successHandler提供更優雅的設置器…

過去的樣板(在這里贊譽您)

現在是時候關注一些更有趣的地方了。

在建立與Facebook的初始成功連接后,立即觸發自定義ConnectionSignUp:

@Override @Transactional public String execute(final Connection<?> connection) {//add new users to the db with its default rolesfinal User user = new User();final String firstName = connection.fetchUserProfile().getFirstName();user.setUsername(generateUniqueUserName(firstName));user.setProviderId(connection.getKey().getProviderId());user.setProviderUserId(connection.getKey().getProviderUserId());user.setAccessToken(connection.createData().getAccessToken());grantRoles(user);userRepository.save(user);return user.getUserId(); }

如您所見,我的版本只是將用戶的連接數據保留為單個JPA對象。 故意僅支持用戶與Facebook上的身份之間的一對一關系。

請注意,我最終從用戶生成的實際令牌中排除了連接屬性。 就像我之前排除了密碼字段(該字段不再是User對象的一部分)一樣:

@JsonIgnore private String accessToken;

走這條路線確實意味著對facebook API的任何調用都需要數據庫查詢其他連接字段。 稍后將對此進行更多介紹。

在用戶通過身份驗證之后,立即觸發自定義AuthenticationSuccessHandler:

@Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth) {// Lookup the complete User object from the databasefinal User user = userService.loadUserByUsername(auth.getName());// Add UserAuthentication to the responsefinal UserAuthentication ua = new UserAuthentication(user);tokenAuthenticationService.addAuthentication(response, ua);super.onAuthenticationSuccess(request, response, auth); }

這看起來很像以前的博客文章中的代碼,但是我必須在TokenAuthenticationService中進行一些更改。 由于客戶端是在重定向之后加載的,因此要在此之前在客戶端保留令牌,必須將其作為cookie發送給客戶端:

public void addAuthentication(HttpServletResponse response, UserAuthentication authentication) {final User user = authentication.getDetails();user.setExpires(System.currentTimeMillis() + TEN_DAYS);final String token = tokenHandler.createTokenForUser(user);// Put the token into a cookie because the client can't capture response// headers of redirects / full page reloads. // (this response triggers a redirect back to "/")response.addCookie(createCookieForToken(token)); }

最終成為最終重定向響應的一部分,如下所示:

成功登錄后,最終重定向回客戶端

成功登錄后,最終重定向回客戶端

最后也是最好的部分是所有代碼結合在一起形成一個非常漂亮的API。 由于Spring Social已經負責創建用戶特定的請求范圍的ConnectionRepository,因此可以通過將以下bean代碼添加到SocialConfigurerAdapter來創建其特定于連接的API:

@Bean @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES) public Facebook facebook(ConnectionRepository repo) { Connection<Facebook> connection = repo.findPrimaryConnection(Facebook.class);return connection != null ? connection.getApi() : null; }

此用戶特定的facebook bean可以在控制器中使用,如下所示:

@Autowired Facebook facebook;@RequestMapping(value = "/api/facebook/details", method = RequestMethod.GET) public FacebookProfile getSocialDetails() {return facebook.userOperations().getUserProfile(); }

客戶端實施

如前所述,令牌現在作為Cookie傳遞給客戶端。 但是,就像以前一樣,服務器端仍然只接受發送到特殊HTTP標頭中的令牌。 承認這是相當隨意的,您可以讓它簡單地接受cookie。 我不希望這樣做,因為它可以防止CSRF攻擊。 (因為無法指示瀏覽器將正確的身份驗證令牌自動添加到請求中。)

因此,在檢索當前用戶詳細信息之前,前端的init方法現在首先嘗試將cookie移至本地存儲:

$scope.init = function () {var authCookie = $cookies['AUTH-TOKEN'];if (authCookie) {TokenStorage.store(authCookie);delete $cookies['AUTH-TOKEN'];}$http.get('/api/user/current').success(function (user) {if (user.username) {$rootScope.authenticated = true;$scope.username = user.username;// For display purposes only$scope.token = JSON.parse(atob(TokenStorage.retrieve().split('.')[0]));}}); };

自定義HTTP標頭的放置在與上次相同的http攔截器中進行處理。

實際的“使用Facebook登錄”按鈕只是觸發整個重定向狂潮的鏈接:

<a href="/auth/facebook"><button>Login with Facebook</button></a>

為了檢查實際的Facebook API是否有效,我添加了另一個按鈕,用于在登錄后顯示來自facebook的用戶詳細信息。

最后的話(建議)

將我的自定義版本的JWT與社交身份驗證集成在一起是一個很大的旅程。 有些部分不那么瑣碎。 就像在將數據庫調用卸載到JWT令牌之間找到一個很好的平衡。 最終,我選擇不與客戶端共享Facebook的訪問令牌,因為只有在使用Facebook的API時才需要它。 這意味著對Facebook的任何查詢都需要數據庫調用來獲取令牌。 實際上,這意味著對具有@Autowired Facebook服務的任何控制器的任何REST API調用都會導致獲取請求令牌的過程非常熱烈,這是請求范圍的Bean創建的一部分。 但是,通過使用專用控制器進行Facebook調用可以輕松緩解這種情況,但這絕對是需要注意的。

如果您打算實際使用此代碼并進行Facebook API調用,請確保您的JWT令牌在facebook令牌之前過期(當前有效期為60天)。 最好在檢測到故障時實施強制重新登錄,因為任何重新登錄都會自動將新獲取的facebook令牌存儲在數據庫中。

您可以在github上找到完整的工作示例。 也可以在此處找到有關如何運行它的詳細信息。 我已經包含了Maven和Gradle構建文件。

翻譯自: https://www.javacodegeeks.com/2015/01/stateless-spring-security-part-3-jwt-social-authentication.html

總結

以上是生活随笔為你收集整理的Spring Stateless State Security第3部分:JWT +社会认证的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久中文免费视频 | 玖玖综合网 | 黄色1级片 | 天天色天天色天天色 | 午夜色av | av影院在线 | 国产一级视频免费观看 | 亚洲vs天堂 | 日韩人妻一区二区三区蜜桃 | 日日操夜夜爱 | 午夜在线视频观看 | 国产精品一区二区av | 国产最新自拍视频 | 丁香婷婷网 | 欧洲亚洲综合 | 久久精品五月天 | 韩国福利一区 | 竹菊影视日韩一区二区 | 男女无遮挡猛进猛出 | 国产成人主播 | 国产一级av毛片 | 色婷婷综合久久久久中文一区二区 | 欧美黑吊大战白妞欧美大片 | 久久国产精品首页 | 日韩乱码在线观看 | 91av爱爱| 日韩精品亚洲精品 | 日韩视频在线免费 | 国产精品怡红院 | 亚洲精品国产精品国自产网站 | 国产精品6666 | 西西人体高清44rt·net | 97精品在线视频 | 91大神精品在线 | 玉足调教丨vk24分钟 | 国产精品一国产精品 | 日本久久久久久久久久 | 免费超碰在线观看 | 色操插 | 97精品国产97久久久久久免费 | 成人资源在线观看 | 精品九九九 | 超碰在线网 | 免费av一区二区三区 | 337p亚洲欧洲色噜噜噜 | 91 免费看片 | 91在线一区二区三区 | 国产午夜福利100集发布 | 91干干| 免费荫蒂添的好舒服视频 | 韩日一区 | 精品夜夜澡人妻无码av | 2019天天干 | 亚洲黄色中文字幕 | 亚洲午夜久久久久 | av专区在线 | 欧美黄色一区 | 在线视频91 | 69视频国产| 国产精品一区二区三区四区五区 | 日韩少妇一区二区三区 | www.黄在线观看 | 在线免费色 | 一本一本久久a久久精品综合麻豆 | 日韩电影第一页 | 中文字幕a级片 | 亚洲三级成人 | 免费爱爱网址 | 国产在线观看成人 | 成人在线h| 超碰狠狠操 | 中国免费黄色片 | 成人毛片大全 | 人人狠狠综合久久亚洲 | 国产福利视频一区 | 2021国产精品| 日韩一级久久 | 欧美成人高潮一二区在线看 | 日本高清不卡在线 | 狠狠艹视频 | 亚洲国产一区二区三区 | 伦理片久久| 91色九色 | 日本天堂免费 | 又黄又色又爽 | 欧美在线网站 | 国产精品免费视频一区二区 | 涩涩网站在线 | 成人久久久 | 日韩欧美成人一区二区三区 | 久久久国产成人 | 波多野结衣欲乱上班族 | 免费在线看污 | 国产亚洲精品久久久久久无几年桃 | 小明天天看 | 好好热视频 | 91在线免费网站 | 国产精品无码久久久久一区二区 | 中文字幕免费高清 |