Omdiriger til forskellige sider efter login med Spring Security

1. Oversigt

Et almindeligt krav til en webapplikation er at omdirigere forskellige typer brugere til forskellige sider efter login. Et eksempel på dette ville være at omdirigere standardbrugere til en /hjemmeside.html side og admin brugere til en /console.html side for eksempel.

Denne artikel viser, hvordan du hurtigt og sikkert implementerer denne mekanisme ved hjælp af Spring Security. Artiklen bygger også oven på Spring MVC-tutorial, der beskæftiger sig med opsætning af de vigtigste MVC-ting, der er nødvendige for projektet.

2. Spring Security Configuration

Spring Security leverer en komponent, der har det direkte ansvar for at beslutte, hvad de skal gøre efter en vellykket godkendelse - AuthenticationSuccessHandler.

2.1. Grundlæggende konfiguration

Lad os først konfigurere en grundlæggende @Konfiguration og @Service klasse:

@Configuration @EnableWebSecurity offentlig klasse SecSecurityConfig udvider WebSecurityConfigurerAdapter {@Override beskyttet ugyldig konfiguration (endelig HttpSecurity http) kaster Undtagelse {http .authorizeRequests () // ... endpoints .formLogin () .loginPage ("/ loginlog.html".) ("/ login") .defaultSuccessUrl ("/ homepage.html", sandt) // ... anden konfiguration}}

Den del af denne konfiguration, der skal fokuseres på, er defaultSuccessUrl () metode. Efter et vellykket login vil enhver bruger blive omdirigeret til hjemmeside.html.

Desuden er vi nødt til at konfigurere brugere og deres roller. Med henblik på denne artikel implementerer vi en simpel UserDetailService med to brugere, der hver har en enkelt rolle. For mere om dette emne, læs vores artikel Spring Security - Roller og privilegier.

@Service offentlig klasse MyUserDetailsService implementerer UserDetailsService {private Map-roller = ny HashMap (); @PostConstruct offentlig ugyldig init () {role.put ("admin2", ny bruger ("admin", "{noop} admin1", getAuthority ("ROLE_ADMIN"))); roller.put ("bruger2", ny bruger ("bruger", "{noop} bruger1", getAuthority ("ROLE_USER"))); } @ Override offentlige UserDetails loadUserByUsername (streng brugernavn) {return role.get (brugernavn); } privat liste getAuthority (strengrolle) {returner Collections.singletonList (ny SimpleGrantedAuthority (rolle)); }} 

Bemærk også, at vi i dette enkle eksempel ikke bruger en kodeordkoder, derfor er adgangskoderne præfikset med {noop}.

2.2. Tilføjelse af Custom Succes Handler

Vi har nu to brugere med de to forskellige roller: bruger og admin. Efter et vellykket login omdirigeres begge til hompeage.html. Lad os se på, hvordan vi kan have en anden omdirigering baseret på brugerens rolle.

Først skal vi definere en brugerdefineret succeshåndterer som en bønne:

@Bean public AuthenticationSuccessHandler myAuthenticationSuccessHandler () {returner ny MySimpleUrlAuthenticationSuccessHandler (); } 

Og udskift derefter defaultSuccessUrl ring med succesHandler metode, der accepterer vores brugerdefinerede succeshåndterer som parameter:

@ Override beskyttet ugyldig konfiguration (endelig HttpSecurity http) kaster undtagelse {http .authorizeRequests () // endpoints .formLogin () .loginPage ("/ login.html") .loginProcessingUrl ("/ login") .successHandler (myAuthenticationSuccessHandler () // anden konfiguration} 

2.3. XML-konfiguration

Før vi ser på implementeringen af ​​vores brugerdefinerede succeshåndterer, skal vi også se på den tilsvarende XML-konfiguration:

3. Den tilpassede godkendelses succeshandler

udover det AuthenticationSuccessHandler interface giver Spring også en fornuftig standard for denne strategikomponent - AbstractAuthenticationTargetUrlRequestHandler og en simpel implementering - SimpleUrlAuthenticationSuccessHandler. Disse implementeringer vil typisk bestemme URL'en efter login og udføre en omdirigering til den URL.

Selvom det er noget fleksibelt, tillader mekanismen til at bestemme denne mål-URL ikke, at bestemmelsen kan udføres programmatisk - så vi implementerer grænsefladen og leverer en brugerdefineret implementering af succeshåndteringen. Denne implementering vil bestemme URL'en, som brugeren skal omdirigere til efter login, baseret på brugerens rolle.

Først og fremmest er vi nødt til at tilsidesætte onAuthenticationSuccess metode:

offentlig klasse MySimpleUrlAuthenticationSuccessHandler implementerer AuthenticationSuccessHandler {beskyttet Log-logger = LogFactory.getLog (this.getClass ()); private RedirectStrategy redirectStrategy = ny DefaultRedirectStrategy (); @ Overstyr offentlig tomrum påAuthenticationSuccess (HttpServletRequest-anmodning, HttpServletResponse-svar, godkendelsesgodkendelse) kaster IOException {håndtag (anmodning, svar, godkendelse); clearAuthenticationAttributes (anmodning); } 

Vores tilpassede metode kalder to hjælpemetoder:

beskyttet ugyldigt håndtag (HttpServletRequest-anmodning, HttpServletResponse-svar, godkendelsesgodkendelse) kaster IOException {String targetUrl = determinTargetUrl (godkendelse); if (response.isCommitted ()) {logger.debug ("Svar er allerede begået. Kan ikke omdirigere til" + targetUrl); Vend tilbage; } redirectStrategy.sendRedirect (anmodning, svar, targetUrl); } 

Hvor den følgende metode fungerer, og kortlægger brugeren til mål-URL:

beskyttet String determTargetUrl (endelig godkendelsesgodkendelse) {Map roleTargetUrlMap = new HashMap (); roleTargetUrlMap.put ("ROLE_USER", "/homepage.html"); roleTargetUrlMap.put ("ROLE_ADMIN", "/console.html"); endelige indsamlingsmyndigheder = authentication.getAuthorities (); for (endelig GrantedAuthority givesAuthority: autoriteter) {String AuthorityName = givenAuthority.getAuthority (); hvis (roleTargetUrlMap.containsKey (autoritetsnavn)) {returnerer rollTargetUrlMap.get (autoritetsnavn); }} smid ny IllegalStateException (); } 

Bemærk, at denne metode returnerer den kortlagte URL for den første rolle, som brugeren har. Så hvis en bruger har flere roller, vil den tilknyttede URL være den, der matcher den første rolle, der er angivet i myndigheder kollektion.

beskyttet ugyldigt clearAuthenticationAttributes (HttpServletRequest anmodning) {HttpSession session = request.getSession (false); hvis (session == null) {return; } session.removeAttribute (WebAttributs.AUTHENTICATION_EXCEPTION); }

Det determinTargetUrl - som er kernen i strategien - ser blot på typen af ​​bruger (bestemt af autoriteten) og vælger mål-URL'en baseret på denne rolle.

Så en admin bruger - bestemt af ROLE_ADMIN autoritet - omdirigeres til konsolesiden efter login, mens standardbrugeren - som bestemt af ROLE_USER - omdirigeres til hjemmesiden.

4. Konklusion

Som altid er koden præsenteret i denne artikel tilgængelig på GitHub. Dette er et Maven-baseret projekt, så det skal være let at importere og køre som det er.