Einfaches Single Sign-On mit Spring Security OAuth2
1. Überblick
In diesem Tutorial wird erläutert, wie Sie SSO - Single Sign On - mithilfe von Spring Security OAuth und Spring Boot implementieren.
Wir verwenden drei separate Anwendungen:
-
Ein Autorisierungsserver - das ist der zentrale Authentifizierungsmechanismus
-
Zwei Client-Anwendungen: Die Anwendungen, die SSO verwenden
Ganz einfach ausgedrückt: Wenn ein Benutzer versucht, auf eine gesicherte Seite in der Client-App zuzugreifen, wird er über den Authentifizierungsserver zur Authentifizierung umgeleitet.
Und wir werden den Grant-TypAuthorization Codeaus OAuth2 verwenden, um die Delegierung der Authentifizierung voranzutreiben.
Weitere Lektüre:
Spring Security 5 - OAuth2-Anmeldung
In Spring Security 5 erfahren Sie, wie Sie Benutzer mit Facebook, Google oder anderen Anmeldeinformationen mithilfe von OAuth2 authentifizieren.
Neu in Spring Security OAuth2 - Ansprüche überprüfen
Schneller praktischer Einstieg in die neue Claim Verification-Unterstützung in Spring Security OAuth.
Ein sekundäres Facebook-Login mit Spring Social
Ein kurzer Blick auf die Implementierung einer Facebook-gesteuerten Authentifizierung neben einer Standard-Spring-App für die Formularanmeldung.
Bevor wir anfangen - ein wichtiger Hinweis. Denken Sie daran, dassthe Spring Security core team is in the process of implementing a new OAuth2 stack - mit einigen Aspekten bereits und einige noch in Bearbeitung.
Hier ist ein kurzes Video, das Ihnen einen Kontext zu diesen Bemühungen gibt:
Okay, lass uns gleich einsteigen.
2. Die Client-App
Beginnen wir mit unserer Client-Anwendung. Wir werden natürlich Spring Boot verwenden, um die Konfiguration zu minimieren:
2.1. Maven-Abhängigkeiten
Zunächst benötigen wir die folgenden Abhängigkeiten in unserenpom.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. Sicherheitskonfiguration
Als nächstes der wichtigste Teil, die Sicherheitskonfiguration unserer Client-Anwendung:
@Configuration
@EnableOAuth2Sso
public class UiSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**")
.permitAll()
.anyRequest()
.authenticated();
}
}
Der Kern dieser Konfiguration ist natürlich die@EnableOAuth2Sso-Anmerkung, die wir zum Aktivieren von Single Sign On verwenden.
Beachten Sie, dass wir dieWebSecurityConfigurerAdapter erweitern müssen - ohne sie werden alle Pfade gesichert - damit die Benutzer umgeleitet werden, um sich anzumelden, wenn sie versuchen, auf eine Seite zuzugreifen. In unserem Fall sind die Index- und Anmeldeseiten die einzigen Seiten, auf die ohne Authentifizierung zugegriffen werden kann.
Schließlich haben wir auch eineRequestContextListener-Bean definiert, um Anforderungsbereiche zu verarbeiten.
Und dieapplication.yml:
server:
port: 8082
servlet:
context-path: /ui
session:
cookie:
name: UISESSION
security:
basic:
enabled: false
oauth2:
client:
clientId: SampleClientId
clientSecret: secret
accessTokenUri: http://localhost:8081/auth/oauth/token
userAuthorizationUri: http://localhost:8081/auth/oauth/authorize
resource:
userInfoUri: http://localhost:8081/auth/user/me
spring:
thymeleaf:
cache: false
Ein paar kurze Notizen:
-
Wir haben die Standardauthentifizierung deaktiviert
-
accessTokenUri ist der URI zum Abrufen der Zugriffstoken
-
userAuthorizationUri ist der Autorisierungs-URI, zu dem Benutzer umgeleitet werden
-
userInfoUriist der URI des Benutzerendpunkts, um aktuelle Benutzerdetails abzurufen
Beachten Sie auch, dass wir in unserem Beispiel hier unseren Authorization Server eingeführt haben, aber natürlich auch andere Drittanbieter wie Facebook oder GitHub verwenden können.
2.3. Vorderes Ende
Schauen wir uns nun die Front-End-Konfiguration unserer Client-Anwendung an. Darauf werden wir uns hier nicht konzentrieren, hauptsächlich weil wiralready covered in on the site.
Unsere Kundenanwendung hier hat ein sehr einfaches Frontend; Hier sind dieindex.html:
Spring Security SSO
Login
Und diesecuredPage.html:
Secured Page
Welcome, Name
Auf der SeitesecuredPage.htmlmussten die Benutzer authentifiziert werden. Wenn ein nicht authentifizierter Benutzer versucht, aufsecuredPage.html zuzugreifen, wird er zuerst zur Anmeldeseite umgeleitet.
3. Der Auth-Server
Lassen Sie uns nun unseren Autorisierungsserver hier diskutieren.
3.1. Maven-Abhängigkeiten
Zuerst müssen wir die Abhängigkeiten in unserenpom.xml definieren:
org.springframework.boot
spring-boot-starter-web
org.springframework.security.oauth
spring-security-oauth2
2.3.3.RELEASE
3.2. OAuth-Konfiguration
Es ist wichtig zu verstehen, dass wir den Autorisierungsserver und den Ressourcenserver hier zusammen als eine einzige bereitstellbare Einheit ausführen.
Beginnen wir mit der Konfiguration unseres Ressourcenservers, der gleichzeitig unsere primäre Startanwendung ist:
@SpringBootApplication
@EnableResourceServer
public class AuthorizationServerApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AuthorizationServerApplication.class, args);
}
}
Dann konfigurieren wir unseren Autorisierungsserver:
@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
public void configure(
AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("SampleClientId")
.secret(passwordEncoder.encode("secret"))
.authorizedGrantTypes("authorization_code")
.scopes("user_info")
.autoApprove(true)
.redirectUris(
"http://localhost:8082/ui/login","http://localhost:8083/ui2/login");
}
}
Beachten Sie, dass wir nur einen einfachen Client mit dem Grant-Typauthorization_codeaktivieren.
Beachten Sie außerdem, wieautoApprove auf true gesetzt ist, damit wir nicht umgeleitet und heraufgestuft werden, um Bereiche manuell zu genehmigen.
3.3. Sicherheitskonfiguration
Zunächst deaktivieren wir die Standard-Standardauthentifizierung über unsereapplication.properties:
server.port=8081
server.servlet.context-path=/auth
Gehen wir nun zur Konfiguration und definieren einen einfachen Formularanmeldemechanismus:
@Configuration
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.antMatchers("/login", "/oauth/authorize")
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("john")
.password(passwordEncoder().encode("123"))
.roles("USER");
}
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
Beachten Sie, dass wir die einfache In-Memory-Authentifizierung verwendet haben, diese jedoch einfach durch ein benutzerdefiniertesuserDetailsServiceersetzen können.
3.4. Benutzerendpunkt
Abschließend erstellen wir unseren Benutzerendpunkt, den wir zuvor in unserer Konfiguration verwendet haben:
@RestController
public class UserController {
@GetMapping("/user/me")
public Principal user(Principal principal) {
return principal;
}
}
Dies gibt natürlich die Benutzerdaten mit einer JSON-Darstellung zurück.
4. Fazit
In diesem kurzen Tutorial haben wir uns auf die Implementierung von Single Sign On mit Spring Security Oauth2 und Spring Boot konzentriert.
Wie immer kann der vollständige Quellcodeover on GitHub gefunden werden.