Autentifikacija pomoću Reddit OAuth2 i Spring Security

1. Pregled

U ovom uputstvu koristit ćemo Spring Security OAuth za autentifikaciju pomoću Reddit API-ja.

2. Konfiguracija Maven

Prvo, da bismo koristili Spring Security OAuth - moramo dodati sljedeću ovisnost o našoj pom.xml (naravno uz bilo koju drugu ovisnost o proljeću koju biste mogli koristiti):

 org.springframework.security.oauth spring-security-oauth2 2.0.6.OBLAŽENJE 

3. Konfigurirajte OAuth2 klijenta

Dalje - konfigurirajmo naš OAuth2 klijent - OAuth2RestTemplate - i a reddit.svojstva datoteka za sva svojstva povezana s autentifikacijom:

@Configuration @ EnableOAuth2Client @PropertySource ("classpath: reddit.properties") zaštićena statička klasa ResourceConfiguration {@Value ("$ {accessTokenUri}") private String accessTokenUri; @Value ("$ {userAuthorizationUri}") privatni niz userAuthorizationUri; @Value ("$ {clientID}") privatni niz clientID; @Value ("$ {clientSecret}") privatni niz clientSecret; @Bean public OAuth2ProtectedResourceDetails reddit () {AuthorizationCodeResourceDetails detalji = novi AuthorizationCodeResourceDetails (); detalji.setId ("reddit"); details.setClientId (clientID); details.setClientSecret (clientSecret); details.setAccessTokenUri (accessTokenUri); details.setUserAuthorizationUri (userAuthorizationUri); detalji.setTokenName ("oauth_token"); details.setScope (Arrays.asList ("identitet")); details.setPreEstablishedRedirectUri ("// localhost / login"); details.setUseCurrentUri (netačno); detalji povrata; } @Bean public OAuth2RestTemplate redditRestTemplate (OAuth2ClientContext clientContext) {OAuth2RestTemplate template = new OAuth2RestTemplate (reddit (), clientContext); AccessTokenProvider accessTokenProvider = novi AccessTokenProviderChain (nizovi. AsList (novi MyAuthorizationCodeAccessTokenProvider (), novi ImplicitAccessTokenProvider (), novi ResourceOwnerPasswordAccessTokenProviderCredenCroverCentral (ClientProvider) template.setAccessTokenProvider (accessTokenProvider); predložak za povratak; }}

I “reddit.svojstva“:

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

Možete dobiti svoj vlastiti tajni kôd izradom aplikacije Reddit sa //www.reddit.com/prefs/apps/

Koristit ćemo OAuth2RestTemplate do:

  1. Nabavite pristupni token potreban za pristup udaljenom resursu.
  2. Pristupite udaljenom resursu nakon dobivanja pristupnog tokena.

Također imajte na umu kako smo dodali opseg “identitet”U Reddit OAuth2ProtectedResourceDetails kako bismo kasnije mogli doći do podataka o korisničkom računu.

4. Prilagođeno AuthorizationCodeAccessTokenProvider

Implementacija Reddit OAuth2 malo se razlikuje od standardne. I tako - umjesto da elegantno proširite AuthorizationCodeAccessTokenProvider - zapravo moramo nadjačati neke njegove dijelove.

Postoje github problemi s praćenjem poboljšanja zbog kojih to neće biti potrebno, ali ti problemi još nisu gotovi.

Jedna od nestandardnih stvari koje Reddit čini jest - kada preusmjerimo korisnika i zatražimo da se ovjeri pomoću Reddita, u URL-u za preusmjeravanje moramo imati neke prilagođene parametre. Točnije - ako tražimo token za trajni pristup od Reddita - moramo dodati parametar “trajanje"S vrijednošću"trajni“.

Dakle, nakon produženja AuthorizationCodeAccessTokenProvider - dodali smo ovaj parametar u getRedirectForAuthorization () metoda:

 requestParameters.put ("trajanje", "trajno");

Potpuni izvorni kod možete provjeriti ovdje.

5. The Inicijalizator poslužitelja

Dalje - stvorimo svoj običaj Inicijalizator poslužitelja.

Moramo dodati zrno filtra s id-om oauth2ClientContextFilter, tako da ga možemo koristiti za pohranu trenutnog konteksta:

javna klasa ServletInitializer proširuje AbstractDispatcherServletInitializer {@Override protected WebApplicationContext createServletApplicationContext () {AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext (); context.register (WebConfig.class, SecurityConfig.class); povratni kontekst; } @Override protected String [] getServletMappings () {return new String [] {"/"}; } @Override zaštićen WebApplicationContext createRootApplicationContext () {return null; } @Override public void onStartup (ServletContext servletContext) baca ServletException {super.onStartup (servletContext); registerProxyFilter (servletContext, "oauth2ClientContextFilter"); registerProxyFilter (servletContext, "springSecurityFilterChain"); } privatna praznina registerProxyFilter (ServletContext servletContext, naziv niza) {DelegatingFilterProxy filter = novi DelegatingFilterProxy (ime); filter.setContextAttribute ("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher"); servletContext.addFilter (ime, filtar) .addMappingForUrlPatterns (null, false, "/ *"); }}

6. MVC konfiguracija

Sada - pogledajmo našu MVC konfiguraciju naše jednostavne web-aplikacije:

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

7. Sigurnosna konfiguracija

Dalje - pogledajmo glavna konfiguracija Spring Security:

@Configuration @EnableWebSecurity javna klasa SecurityConfig proširuje WebSecurityConfigurerAdapter {@Override zaštićena void konfiguracija (AuthenticationManagerBuilder auth) baca iznimku {auth.inMemoryAuthentication (); } @Override zaštićena void konfiguracija (HttpSecurity http) baca Iznimku {http .anonymous (). Disable () .csrf (). Disable () .authorizeRequests () .antMatchers ("/ home.html"). HasRole ("USER" ) .and () .httpBasic () .authenticationEntryPoint (oauth2AuthenticationEntryPoint ()); } private LoginUrlAuthenticationEntryPoint oauth2AuthenticationEntryPoint () {return new LoginUrlAuthenticationEntryPoint ("/ login"); }}

Napomena: Dodali smo jednostavnu sigurnosnu konfiguraciju koja preusmjerava na “/prijaviti se”Koji dobivaju korisničke podatke i učitavaju provjeru autentičnosti iz njih - kako je objašnjeno u sljedećem odjeljku.

8. RedditController

Sada - pogledajmo naš kontroler RedditController.

Koristimo metodu redditLogin () za dobivanje korisničkih podataka s njegovog Reddit računa i učitavanje provjere autentičnosti s njega - kao u sljedećem primjeru:

@Controller javna klasa RedditController {@Autowired private OAuth2RestTemplate redditRestTemplate; @RequestMapping ("/ login") javni niz 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); return "preusmjeravanje: home.html"; }}

Zanimljiv detalj ove varljivo jednostavne metode - predložak reddit provjerava je li pristupni token dostupan prije izvršavanja bilo kojeg zahtjeva; stječe žeton ako nije dostupan.

Dalje - informacije predstavljamo našem vrlo pojednostavljenom prednjem dijelu.

9. home.jsp

Napokon - pogledajmo home.jsp - za prikaz podataka preuzetih iz korisnikovog Reddit računa:

10. Zaključak

U ovom uvodnom članku istražili smo autentičnost pomoću Reddit OAuth2 API-ja i prikazivanje nekih vrlo osnovnih podataka u jednostavnom prednjem dijelu.

Sad kad smo provjerili autentičnost, istražit ćemo još zanimljivih stvari s Reddit API-jem u sljedećem članku ove nove serije.

The puna provedba ovog vodiča možete pronaći u projektu github - ovo je projekt zasnovan na Eclipseu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.


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