日韩性视频-久久久蜜桃-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 +社会认证的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 性折磨bdsm欧美激情另类 | 国产视频麻豆 | 新版红楼梦在线高清免费观看 | 一级做a在线观看 | 欧美日在线观看 | 亚洲欧美www| 名校风暴在线观看免费高清完整 | 国产精品人人爽人人爽 | 神马午夜影院 | 亚洲人天堂| 91av官网| 久草精品在线观看视频 | 贝利弗山的秘密在线观看 | 亚洲一区二区三区视频在线 | 美女狠狠干 | 欧美一区二区不卡视频 | av小说天堂网 | 午夜爽爽视频 | 国产又粗又猛又黄视频 | 亚洲天堂2013 | 亚洲色图美腿丝袜 | 无码av免费精品一区二区三区 | 精品人妻一区二区三区久久嗨 | 日本黄色片在线播放 | 理论片午午伦夜理片影院99 | 国产精品日韩专区 | 午夜国产一区二区三区 | 国产又黄又猛的视频 | 精品国产一区二区三区性色 | 国产一二三区精品 | 日韩av电影手机在线观看 | 久久久久久久久久一区二区三区 | 免费看污视频的网站 | 久久超碰在线 | 久久日视频| 日本做爰高潮又黄又爽 | 亚洲天堂手机版 | 96视频在线观看 | 国产精品久久久久精 | 搞逼综合网 | 伊人tv| 男女在楼梯上高潮做啪啪 | 国产视频污在线观看 | 国产日韩欧美在线观看视频 | 一级特黄性色生活片 | 亚洲男人皇宫 | 91麻豆国产福利精品 | 国内精品小视频 | 亚洲av无码一区二区乱子伦as | 色哒哒影院 | 亚洲精品国产suv一区 | 国产农村老头老太视频 | 噜噜色成人| 快播91 | 女优色图 | 成人在线影片 | 少妇人妻真实偷人精品视频 | 欧美在线视频二区 | 国产精品va无码一区二区三区 | 久久精品国产欧美亚洲人人爽 | yy6080久久| 欧美在线色 | 蜜臀网在线 | 香蕉久久a毛片 | 先锋影音一区二区三区 | 99精品乱码国产在线观看 | 老司机免费在线视频 | 黄色茄子视频 | 精品久久久精品 | 日本免费在线观看 | 三上悠亚 电影 | 日韩欧美在线观看免费 | 第四色影音先锋 | 日韩黄色一级视频 | 99久久亚洲精品日本无码 | 中日韩男男gay无套 人人草人人干 | 欧美色xxx | 波多野结衣高清电影 | 亚洲精华国产精华精华液网站 | 小泽玛利亚一区二区三区在线观看 | 色网在线免费观看 | 欧美色一区二区三区在线观看 | 久久国产人妻一区二区免色戒电影 | av老司机福利| 国产精品不卡一区 | 日韩在线电影一区二区 | 少女情窦初开的第4集在线观看 | 成人免费视频观看 | 国产私密视频 | 精品成人在线视频 | av国产网站 | 黄页网站视频 | 外国av在线 | 欧美在线观看一区二区三区 | 国产精品久久久久久久久久 | 日本免费一区二区三区四区 | 黄色在线观看网站 | 国产精品99精品无码视亚 | www.啪啪.com|