Eenvoudige eenmalige aanmelding met Spring Security OAuth2 (legacy-stack)

1. Overzicht

In deze tutorial bespreken we hoe SSO - Single Sign On - geïmplementeerd kan worden met Spring Security OAuth en Spring Boot.

We gebruiken drie afzonderlijke applicaties:

  • Een autorisatieserver - het centrale authenticatiemechanisme
  • Twee clienttoepassingen: de toepassingen die gebruikmaken van SSO

Heel eenvoudig gezegd: wanneer een gebruiker probeert toegang te krijgen tot een beveiligde pagina in de client-app, wordt hij of zij eerst omgeleid om zich te authenticeren, via de authenticatieserver.

En we gaan de Authorisatie Code verlenen type uit OAuth2 om de delegatie van authenticatie aan te sturen.

Opmerking: dit artikel maakt gebruik van het verouderde Spring OAuth-project. Voor de versie van dit artikel met de nieuwe Spring Security 5-stack, bekijk ons ​​artikel Simple Single Sign-On met Spring Security OAuth2.

2. De Client-app

Laten we beginnen met onze clienttoepassing; we zullen natuurlijk Spring Boot gebruiken om de configuratie te minimaliseren:

2.1. Afhankelijkheden van Maven

Ten eerste hebben we de volgende afhankelijkheden nodig in onze pom.xml:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-security org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure 2.0.1.RELEASE org.springframework.boot spring-boot-starter-thymeleaf org.thymeleaf.extras thymeleaf-extras-springsecurity4 

2.2. Beveiligingsconfiguratie

Vervolgens het belangrijkste onderdeel, de beveiligingsconfiguratie van onze clienttoepassing:

@Configuration @ EnableOAuth2Sso public class UiSecurityConfig breidt WebSecurityConfigurerAdapter uit {@Override public void configure (HttpSecurity http) gooit uitzondering {http.antMatcher ("/ **") .authorizeRequests () .antMatchers ("/", "/ login **") .permitAll () .anyRequest () .authenticated (); }}

Het kernonderdeel van deze configuratie is natuurlijk de @ EnableOAuth2Sso annotatie die we gebruiken om Single Sign On in te schakelen.

Merk op dat we het WebSecurityConfigurerAdapter - zonder dit worden alle paden beveiligd - zodat de gebruikers worden omgeleid om in te loggen wanneer ze proberen toegang te krijgen tot een pagina. In ons geval zijn de index- en inlogpagina's de enige pagina's die zonder authenticatie kunnen worden geopend.

Ten slotte hebben we ook een RequestContextListener bean om het bereik van verzoeken af ​​te handelen.

En de application.yml:

server: poort: 8082 servlet: contextpad: / ui sessie: cookie: naam: UISESSION security: basic: enabled: false oauth2: client: clientId: SampleClientId clientSecret: secret accessTokenUri: // localhost: 8081 / auth / oauth / token userAuthorizationUri: // localhost: 8081 / auth / oauth / authorize resource: userInfoUri: // localhost: 8081 / auth / user / me spring: thymeleaf: cache: false

Een paar korte opmerkingen:

  • we hebben de standaard basisverificatie uitgeschakeld
  • accessTokenUri is de URI om de toegangstokens te verkrijgen
  • userAuthorizationUri is de autorisatie-URI waarnaar gebruikers worden omgeleid
  • userInfoUri de URI van het gebruikerseindpunt om de huidige gebruikersgegevens te verkrijgen

Merk ook op dat we in ons voorbeeld hier onze autorisatieserver hebben uitgerold, maar we kunnen natuurlijk ook andere externe providers gebruiken, zoals Facebook of GitHub.

2.3. Voorkant

Laten we nu eens kijken naar de front-end-configuratie van onze clienttoepassing. Daar gaan we ons hier niet op concentreren, vooral omdat we het al op de site hebben behandeld.

Onze klanttoepassing heeft hier een heel eenvoudige front-end; hier is de index.html:

 Log in

En de securePage.html:

 Welkom, naam

De securePage.html pagina had de gebruikers nodig om te worden geverifieerd. Als een niet-geauthenticeerde gebruiker toegang probeert te krijgen securePage.html, worden ze eerst doorgestuurd naar de inlogpagina.

3. De Auth-server

Laten we nu onze autorisatieserver hier bespreken.

3.1. Afhankelijkheden van Maven

Eerst moeten we de afhankelijkheden in onze pom.xml:

 org.springframework.boot spring-boot-starter-web org.springframework.security.oauth spring-security-oauth2 2.3.3.RELEASE 

3.2. OAuth-configuratie

Het is belangrijk om te begrijpen dat we de Authorization Server en de Resource Server hier samen gaan gebruiken, als een enkele inzetbare eenheid.

Laten we beginnen met de configuratie van onze Resource Server - die ook dienst doet als onze primaire Boot-applicatie:

@SpringBootApplication @EnableResourceServer public class AuthorizationServerApplication breidt SpringBootServletInitializer uit {public static void main (String [] args) {SpringApplication.run (AuthorizationServerApplication.class, args); }}

Vervolgens configureren we onze autorisatieserver:

@Configuration @EnableAuthorizationServer openbare klasse AuthServerConfig breidt AuthorizationServerConfigurerAdapter uit {@Autowired private BCryptPasswordEncoder passwordEncoder; @Override public void configure (AuthorizationServerSecurityConfigurer oauthServer) genereert Uitzondering {oauthServer.tokenKeyAccess ("allowAll ()") .checkTokenAccess ("isAuthenticated ()"); } @Override public void configure (ClientDetailsServiceConfigurer clients) genereert Uitzondering {clients.inMemory () .withClient ("SampleClientId") .secret (passwordEncoder.encode ("secret")) .authorizedGrantTypes ("autorisatiecode") .scopes ("user_info" ) .autoApprove (true) .redirectUris ("// localhost: 8082 / ui / login", "// localhost: 8083 / ui2 / login"); }}

Merk op dat we alleen een eenvoudige client inschakelen met behulp van de Authorisatie Code toekenningstype.

Merk ook op hoe autoApprove is ingesteld op true, zodat we niet worden omgeleid en gepromoveerd om scopes handmatig goed te keuren.

3.3. Beveiligingsconfiguratie

Eerst zullen we de standaard basisverificatie uitschakelen via onze application.properties:

server.port = 8081 server.servlet.context-path = / auth

Laten we nu naar de configuratie gaan en een eenvoudig aanmeldingsmechanisme definiëren:

@Configuration @Order (1) public class SecurityConfig breidt WebSecurityConfigurerAdapter uit {@Override protected void configure (HttpSecurity http) gooit uitzondering {http.requestMatchers () .antMatchers ("/ login", "/ oauth / authorize") .en (). authorizeRequests () .anyRequest (). geverifieerd (). en () .formLogin (). allowAll (); } @Override beschermde void configure (AuthenticationManagerBuilder auth) genereert Uitzondering {auth.inMemoryAuthentication () .withUser ("john") .password (passwordEncoder (). Encode ("123")) .roles ("USER"); } @Bean openbare BCryptPasswordEncoder passwordEncoder () {retourneer nieuwe BCryptPasswordEncoder (); }}

Merk op dat we eenvoudige in-memory authenticatie hebben gebruikt, maar we kunnen deze eenvoudig vervangen door een aangepast userDetailsService.

3.4. Eindpunt van de gebruiker

Ten slotte zullen we ons gebruikerseindpunt maken dat we eerder in onze configuratie hebben gebruikt:

@RestController openbare klasse UserController {@GetMapping ("/ user / me") openbare hoofdgebruiker (Principal principal) {return principal; }}

Dit levert natuurlijk de gebruikersgegevens op met een JSON-weergave.

4. Conclusie

In deze korte tutorial hebben we ons gericht op het implementeren van Single Sign-On met Spring Security Oauth2 en Spring Boot.

Zoals altijd is de volledige broncode te vinden op GitHub.