Autentisering med Reddit OAuth2 og Spring Security

1. Oversikt

I denne opplæringen bruker vi Spring Security OAuth til å autentisere med Reddit API.

2. Maven-konfigurasjon

Først, for å kunne bruke Spring Security OAuth - må vi legge til følgende avhengighet til vår pom.xml (selvfølgelig langs enhver annen våravhengighet du måtte bruke):

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

3. Konfigurer OAuth2 Client

Neste - la oss konfigurere vår OAuth2-klient - OAuth2RestTemplate - og en reddit.properties fil for alle autentiseringsrelaterte egenskaper:

@Configuration @ EnableOAuth2Client @PropertySource ("classpath: reddit.properties") beskyttet statisk klasse ResourceConfiguration {@Value ("$ {accessTokenUri}") privat streng accessTokenUri; @Value ("$ {userAuthorizationUri}") privat streng userAuthorizationUri; @Value ("$ {clientID}") privat streng-clientID; @Value ("$ {clientSecret}") privat streng clientSecret; @Bean public OAuth2ProtectedResourceDetails reddit () {AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails (); details.setId ("reddit"); details.setClientId (clientID); details.setClientSecret (clientSecret); details.setAccessTokenUri (accessTokenUri); details.setUserAuthorizationUri (userAuthorizationUri); details.setTokenName ("oauth_token"); details.setScope (Arrays.asList ("identitet")); details.setPreEstablishedRedirectUri ("// localhost / login"); details.setUseCurrentUri (false); returner detaljer; } @Bean offentlig OAuth2RestTemplate redditRestTemplate (OAuth2ClientContext clientContext) {OAuth2RestTemplate mal = ny OAuth2RestTemplate (reddit (), clientContext); AccessTokenProvider accessTokenProvider = ny AccessTokenProviderChain (Arrays. AsList (ny MyAuthorizationCodeAccessTokenProvider (), ny ImplicitAccessTokenProvider (), ny ResourceOwnerPasswordAccessTokenProvider (), ny ClientCredentialsAccessTokenProvider; template.setAccessTokenProvider (accessTokenProvider); returmal; }}

Og “reddit.properties“:

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

Du kan få din egen hemmelige kode ved å opprette en Reddit-app fra //www.reddit.com/prefs/apps/

Vi skal bruke OAuth2RestTemplate til:

  1. Erverve tilgangstokenet som trengs for å få tilgang til den eksterne ressursen.
  2. Få tilgang til den eksterne ressursen etter at du har fått tilgangstokenet.

Legg også merke til hvordan vi la til omfanget “identitet”Til Reddit OAuth2ProtectedResourceDetails slik at vi kan hente brukerinformasjonen senere.

4. Tilpasset AuthorizationCodeAccessTokenProvider

Reddit OAuth2-implementeringen er litt forskjellig fra standarden. Og så - i stedet for elegant å utvide AuthorizationCodeAccessTokenProvider - vi må faktisk overstyre noen deler av det.

Det er github-problemer som sporer forbedringer som gjør at dette ikke er nødvendig, men disse problemene er ikke gjort ennå.

En av de ikke-standardiserte tingene som Reddit gjør er - når vi omdirigerer brukeren og ber ham om å godkjenne med Reddit, må vi ha noen egendefinerte parametere i omdirigerings-URL-en. Mer spesifikt - hvis vi ber om et permanent tilgangstoken fra Reddit - må vi legge til en parameter “varighet”Med verdien“fast“.

Så, etter å ha utvidet AuthorizationCodeAccessTokenProvider - vi har lagt til denne parameteren i getRedirectForAuthorization () metode:

 requestParameters.put ("varighet", "permanent");

Du kan sjekke hele kildekoden herfra.

5. Den ServerInitializer

Neste - la oss lage vår tilpassede ServerInitializer.

Vi må legge til en filterbønne med id oauth2ClientContextFilter, slik at vi kan bruke den til å lagre gjeldende kontekst:

offentlig klasse ServletInitializer utvider AbstractDispatcherServletInitializer {@Override-beskyttet WebApplicationContext createServletApplicationContext () {AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext (); context.register (WebConfig.class, SecurityConfig.class); returnere kontekst; } @ Override-beskyttet streng [] getServletMappings () {returner ny streng [] {"/"}; } @ Override-beskyttet WebApplicationContext createRootApplicationContext () {return null; } @Override public void onStartup (ServletContext servletContext) kaster ServletException {super.onStartup (servletContext); registerProxyFilter (servletContext, "oauth2ClientContextFilter"); registerProxyFilter (servletContext, "springSecurityFilterChain"); } privat ugyldig registerProxyFilter (ServletContext servletContext, String name) {DelegatingFilterProxy filter = new DelegatingFilterProxy (name); filter.setContextAttribute ("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher"); servletContext.addFilter (navn, filter) .addMappingForUrlPatterns (null, false, "/ *"); }}

6. MVC-konfigurasjon

La oss ta en titt på MVC-konfigurasjonen av den enkle webappen vår:

@Configuration @EnableWebMvc @ComponentScan (basePackages = {"org.baeldung.web"}) public class WebConfig implementerer WebMvcConfigurer {@Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer () {return new PropertySourcesPlaceholderConfigurer; } @Bean public ViewResolver viewResolver () {InternalResourceViewResolver viewResolver = ny InternalResourceViewResolver (); viewResolver.setPrefix ("/ WEB-INF / jsp /"); viewResolver.setSuffix (". jsp"); return viewResolver; } @Override public void configureDefaultServletHandling (DefaultServletHandlerConfigurer configurer) {configurer.enable (); } public void addResourceHandlers (ResourceHandlerRegistry registry) {registry.addResourceHandler ("/ resources / **"). addResourceLocations ("/ resources /"); } @Override public void addViewControllers (ViewControllerRegistry registry) {registry.addViewController ("/ home.html"); }}

7. Sikkerhetskonfigurasjon

Neste - la oss ta en titt på den viktigste Spring Security-konfigurasjonen:

@Configuration @EnableWebSecurity offentlig klasse SecurityConfig utvider WebSecurityConfigurerAdapter {@Override-beskyttet tomkonfigurasjon (AuthenticationManagerBuilder auth) kaster Unntak {auth.inMemoryAuthentication (); } @ Override-beskyttet tomkonfigurasjon (HttpSecurity http) kaster unntak {http. Anonym (). Deaktiver () .csrf (). Deaktiver (). Autorisasjonsforespørsler () .antMatchers ("/ home.html"). HasRole ("USER" ) .og () .httpBasic () .authenticationEntryPoint (oauth2AuthenticationEntryPoint ()); } privat LoginUrlAuthenticationEntryPoint oauth2AuthenticationEntryPoint () {return new LoginUrlAuthenticationEntryPoint ("/ login"); }}

Merk: Vi la til en enkel sikkerhetskonfigurasjon som omdirigerer til “/Logg Inn”Som får brukerinformasjonen og laster inn autentisering fra den - som forklart i neste avsnitt.

8. RedditController

La oss ta en titt på kontrolleren vår RedditController.

Vi bruker metode redditLogin () for å få brukerinformasjonen fra Reddit-kontoen sin og laste inn en godkjenning fra den - som i følgende eksempel:

@Controller offentlig klasse RedditController {@Autowired private OAuth2RestTemplate redditRestTemplate; @RequestMapping ("/ login") offentlig String 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); returner "redirect: home.html"; }}

En interessant detalj av denne villedende enkle metoden - reddit-malen sjekker om tilgangstoken er tilgjengelig før du utfører en forespørsel; det får et token hvis en ikke er tilgjengelig.

Neste - vi presenterer informasjonen til vårt veldig enkle frontend.

9. hjem.jsp

Til slutt - la oss ta en titt på hjem.jsp - for å vise informasjonen hentet fra brukerens Reddit-konto:

10. Konklusjon

I denne innledende artikkelen utforsket vi autentisering med Reddit OAuth2 API og vise veldig grunnleggende informasjon i en enkel frontend.

Nå som vi er autentisert, skal vi utforske å gjøre mer interessante ting med Reddit API i neste artikkel i denne nye serien.

De full gjennomføring av denne opplæringen finnes i github-prosjektet - dette er et formørkelsesbasert prosjekt, så det skal være enkelt å importere og kjøre som det er.


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