אימות באמצעות Reddit OAuth2 ואבטחת אביב

1. סקירה כללית

במדריך זה נשתמש ב- Spring Security OAuth לאימות באמצעות ממשק ה- API של Reddit.

2. תצורת Maven

ראשית, על מנת להשתמש ב- Spring Security OAuth - עלינו להוסיף את התלות הבאה שלנו pom.xml (כמובן לאורך כל תלות אביבית אחרת בה אתה משתמש):

 org.springframework.security.oauth spring-security-oauth2 2.0.6.RELEASE 

3. הגדר את תצורת לקוח OAuth2

לאחר מכן - בואו להגדיר את לקוח OAuth2 שלנו - ה- OAuth2RestTemplate - ו reddit.properties קובץ עבור כל המאפיינים הקשורים לאימות:

@Configuration @ EnableOAuth2Client @PropertySource ("classpath: reddit.properties") מחלקה סטטית מוגנת ResourceConfiguration {@Value ("$ {accessTokenUri}") פרטי מחרוזת accessTokenUri; @Value ("$ {userAuthorizationUri}") מחרוזת פרטית userAuthorizationUri; @Value ("$ {clientID}") מזהה לקוח מחרוזת פרטי; @Value ("$ {clientSecret}") clientSecret מחרוזת פרטית; @Bean OAuth2ProtectedResourceDetails ציבורי reddit () {AuthorizationCodeResourceDetails פרטים = חדש AuthorizationCodeResourceDetails (); details.setId ("reddit"); details.setClientId (clientID); details.setClientSecret (clientSecret); details.setAccessTokenUri (accessTokenUri); details.setUserAuthorizationUri (userAuthorizationUri); details.setTokenName ("oauth_token"); details.setScope (Arrays.asList ("זהות")); details.setPreEstablishedRedirectUri ("// localhost / login"); details.setUseCurrentUri (שקר); פרטי החזרה; } @Bean OAuth2RestTemplate ציבורי redditRestTemplate (OAuth2ClientContext clientContext) {תבנית OAuth2RestTemplate = OAuth2RestTemplate חדש (reddit (), clientContext); AccessTokenProvider accessTokenProvider = AccessTokenProviderChain חדש (מערכים. AsList (חדש MyAuthorizationCodeAccessTokenProvider (), חדש ImplicitAccessTokenProvider (), חדש ResourceOwnerPasswordAccessTokenProvider (), חדש ClientCredentialsAccessTokenProvider; template.setAccessTokenProvider (accessTokenProvider); תבנית החזרה; }}

ו"reddit.properties“:

clientID = xxxxxxxx clientSecret = xxxxxxxx accessTokenUri = // www.reddit.com/api/v1/access_token userAuthorizationUri = // www.reddit.com/api/v1/authorize

תוכל לקבל קוד סודי משלך על ידי יצירת אפליקציית Reddit מ- //www.reddit.com/prefs/apps/

אנחנו הולכים להשתמש ב- OAuth2RestTemplate ל:

  1. רכוש את אסימון הגישה הדרוש לגישה למשאב המרוחק.
  2. גש למשאב המרוחק לאחר קבלת אסימון הגישה.

שימו לב גם כיצד הוספנו את ההיקף “זהות”לרדיט OAuth2ProtectedResourceDetails כדי שנוכל לאחזר את פרטי חשבון המשתמשים מאוחר יותר.

4. מותאם אישית AuthorizationCodeAccessTokenProvider

יישום Reddit OAuth2 שונה מעט מהסטנדרט. וכך - במקום להרחיב את האלגנטיות AuthorizationCodeAccessTokenProvider עלינו למעשה לבטל חלקים ממנו.

ישנן בעיות github במעקב אחר שיפורים שגורמים לכך שלא יהיה צורך בכך, אך בעיות אלה טרם נעשו.

אחד הדברים הלא סטנדרטיים שעושה Reddit הוא - כאשר אנו מפנים את המשתמש ומבקשים ממנו לאמת באמצעות Reddit, עלינו שיהיו כמה פרמטרים מותאמים אישית בכתובת האתר להפניה. באופן ספציפי יותר - אם אנו מבקשים אסימון גישה קבוע מ- Reddit - עלינו להוסיף פרמטר “מֶשֶׁך"עם הערך"קבוע“.

אז, לאחר הארכה AuthorizationCodeAccessTokenProvider - הוספנו פרמטר זה ב- getRedirectForAuthorization () שיטה:

 requestParameters.put ("משך זמן", "קבוע");

תוכלו לבדוק את קוד המקור המלא מכאן.

5. ה ServerInitializer

הבא - בואו ניצור את המנהג שלנו ServerInitializer.

עלינו להוסיף שעועית פילטר עם מזהה oauth2ClientContextFilter, כדי שנוכל להשתמש בו לאחסון ההקשר הנוכחי:

מחלקה ציבורית ServletInitializer מרחיב AbstractDispatcherServletInitializer {@Override מוגן WebApplicationContext createServletApplicationContext () {AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext (); context.register (WebConfig.class, SecurityConfig.class); החזרת הקשר; } מחרוזת מוגנת @ Override [] getServletMappings () {להחזיר מחרוזת חדשה [] {"/"}; } @Override מוגן WebApplicationContext createRootApplicationContext () {return null; } @Override חלל ציבורי ב-Startup (ServletContext servletContext) זורק ServletException {super.onStartup (servletContext); registerProxyFilter (servletContext, "oauth2ClientContextFilter"); registerProxyFilter (servletContext, "springSecurityFilterChain"); } registerProxyFilter חלל פרטי (ServletContext servletContext, שם מחרוזת) {DelegatingFilterProxy filter = new DelegatingFilterProxy (name); filter.setContextAttribute ("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher"); servletContext.addFilter (שם, פילטר) .addMappingForUrlPatterns (null, false, "/ *"); }}

6. תצורת MVC

עכשיו - בואו נסתכל על תצורת ה- MVC של אפליקציית האינטרנט הפשוטה שלנו:

@Configuration @EnableWebMvc @ComponentScan (basePackages = {"org.baeldung.web"}) WebConfig בכיתה ציבורית מיישמת WebMvcConfigurer {@Bean ציבור סטטי PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer () {להחזיר PropertySourcesPlaceholderConfigurer חדש; } @Bean Public ViewResolver viewResolver () {InternalResourceViewResolver viewResolver = חדש InternalResourceViewResolver (); viewResolver.setPrefix ("/ WEB-INF / jsp /"); viewResolver.setSuffix (". jsp"); view viewResolver; } @Override public void configureDefaultServletHandling (תצורת תצורת DefaultServletHandlerConfigurer) {configurer.enable (); } ריק ריק addResourceHandlers (הרישום ResourceHandlerRegistry) {registry.addResourceHandler ("/ resources / **"). addResourceLocations ("/ resources /"); } @Override public void addViewControllers (ViewControllerRegistry registry) {registry.addViewController ("/ home.html"); }}

7. תצורת אבטחה

הבא - בואו נסתכל על התצורה העיקרית של Spring Security:

@Configuration @EnableWebSecurity המחלקה הציבורית SecurityConfig מרחיב את WebSecurityConfigurerAdapter {@Override מוגן חלל להגדיר (AuthenticationManagerBuilder auth) זורק חריג {auth.inMemoryAuthentication (); } תצורת הריק המוגנת על ידי @Override (HttpSecurity http) זורקת חריג {http. אנונימי (). השבת () .csrf (). השבת () .authorizeRequests () .antMatchers ("/ home.html"). HasRole ("USER" ) .and () .httpBasic () .authenticationEntryPoint (oauth2AuthenticationEntryPoint ()); } פרטי LoginUrlAuthenticationEntryPoint oauth2AuthenticationEntryPoint () {להחזיר LoginUrlAuthenticationEntryPoint חדש ("/ login"); }}

הערה: הוספנו תצורת אבטחה פשוטה המפנה אל “/התחברות"שמקבלים את פרטי המשתמש וטוענים ממנו אימות - כמוסבר בסעיף הבא.

8. RedditController

עכשיו - בואו נסתכל על הבקר שלנו RedditController.

אנו משתמשים בשיטה redditLogin () כדי לקבל את פרטי המשתמש מחשבון Reddit שלו ולטעון ממנו אימות - כמו בדוגמה הבאה:

@Controller מחלקה ציבורית RedditController {@ אוטומטית פרטית OAuth2RestTemplate redditRestTemplate; @RequestMapping ("/ login") מחרוזת ציבורית redditLogin () {JsonNode node = redditRestTemplate.getForObject ("//oauth.reddit.com/api/v1/me", JsonNode.class); UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken (node.get ("name"). AsText (), redditRestTemplate.getAccessToken (). GetValue (), Arrays.asList (new SimpleGrantedAuthority ("ROLE_USER"))); SecurityContextHolder.getContext (). SetAuthentication (auth); להחזיר "redirect: home.html"; }}

פרט מעניין של שיטה פשוטה ומטעה זו - תבנית ה- reddit בודק אם אסימון הגישה זמין לפני ביצוע בקשה כלשהי; זה רוכש אסימון אם אחד אינו זמין.

לאחר מכן - אנו מציגים את המידע לחזית המאוד פשטנית שלנו.

9. home.jsp

לסיום - בואו נסתכל על home.jsp - כדי להציג את חשבון Reddit של המשתמש שאוחזר במידע:

10. מסקנה

במאמר ההיכרות הזה חקרנו אימות באמצעות ממשק ה- API של Reddit OAuth2 והצגת מידע בסיסי מאוד בחזית פשוטה.

עכשיו, לאחר שאומתנו, אנו נבדוק לעשות דברים מעניינים יותר עם ה- Reddit API במאמר הבא בסדרה חדשה זו.

ה יישום מלא של מדריך זה ניתן למצוא בפרויקט github - זהו פרויקט מבוסס ליקוי חמה, כך שיהיה קל לייבא ולהפעיל אותו כפי שהוא.


$config[zx-auto] not found$config[zx-overlay] not found