Vårsikkerhetsinnloggingsside med kantete
1. Oversikt
I denne opplæringen skal vi lage en påloggingsside ved hjelp av Spring Security med:
- AngularJS
- Vinkel 2, 4, 5 og 6
Eksempelapplikasjonen som vi skal diskutere her består av et klientprogram som kommuniserer med REST-tjenesten, sikret med grunnleggende HTTP-autentisering.
2. Vårens sikkerhetskonfigurasjon
Først av alt, la oss sette opp REST API med Spring Security og Basic Auth:
Slik er den konfigurert:
@Configuration @EnableWebSecurity offentlig klasse BasicAuthConfiguration utvider WebSecurityConfigurerAdapter {@Override beskyttet ugyldig konfigurering (AuthenticationManagerBuilder auth) kaster Unntak {auth .inMemoryAuthentication () .withUser ("bruker") .passord ("passord USER)") .roles. } @ Override beskyttet ugyldig konfigurasjon (HttpSecurity http) kaster unntak {http.csrf (). Deaktiver () .authorizeRequests () .antMatchers ("/ login"). PermitAll () .anyRequest () .authenticated () .and () .httpBasic (); }}
La oss nå lage sluttpunktene. Vår REST-tjeneste vil ha to - en for pålogging og den andre for å hente brukerdata:
@RestController @CrossOrigin offentlig klasse UserController {@RequestMapping ("/ login") offentlig boolsk pålogging (@RequestBody bruker bruker) {return user.getUserName (). Tilsvarer ("bruker") && user.getPassword (). Tilsvarer ("passord "); } @RequestMapping ("/ user") offentlig Hovedbruker (HttpServletRequest-forespørsel) {String authToken = request.getHeader ("Authorization"). Substring ("Basic" .length ()). Trim (); retur () -> ny streng (Base64.getDecoder (). dekode (authToken)). split (":") [0]; }}
På samme måte kan du også sjekke ut vår andre veiledning om Spring Security OAuth2 hvis du er interessert i å implementere en OAuth2-server for autorisasjon.
3. Sette opp vinkelklienten
Nå som vi har opprettet REST-tjenesten, la oss sette opp påloggingssiden med forskjellige versjoner av Angular-klienten.
Eksemplene som vi skal se her bruker npm for avhengighetsstyring og nodejs for å kjøre applikasjonen.
Angular bruker en enkelt sidearkitektur der alle underordnede komponenter (i vårt tilfelle er dette innloggings- og hjemmekomponenter) blir injisert i en vanlig foreldredom.
I motsetning til AngularJS, som bruker JavaScript, bruker Angular versjon 2 og videre TypeScript som hovedspråk. Derfor krever applikasjonen også visse støttefiler som er nødvendige for at den skal fungere riktig.
På grunn av inkrementelle forbedringer av Angular, er filene som trengs forskjellige fra versjon til versjon.
La oss bli kjent med hver av disse:
- systemjs.config.js - systemkonfigurasjoner (versjon 2)
- pakke.json - nodemodulavhengigheter (versjon 2 og utover)
- tsconfig.json - rotnivå Typescript-konfigurasjoner (versjon 2 og fremover)
- tsconfig.app.json - applikasjonsnivå Typeskriptkonfigurasjoner (versjon 4 og utover)
- .vinkel-cli.json - Angular CLI-konfigurasjoner (versjon 4 og 5)
- angular.json - Kantete CLI-konfigurasjoner (versjon 6 og utover)
4. Påloggingsside
4.1. Bruke AngularJS
La oss lage index.html fil og legg til relevante avhengigheter i den:
Siden dette er en enkeltsidig applikasjon, blir alle underordnede komponenter lagt til div-elementet med ng-view attributt basert på rutinglogikken.
La oss nå lage app.js som definerer URL til komponentkartlegging:
(funksjon () {'bruk streng'; kantet .module ('app', ['ngRoute']) .config (config) .run (run); config. $ inject = ['$ routeProvider', '$ locationProvider' ]; funksjonskonfigurasjon ($ routeProvider, $ locationProvider) {$ routeProvider.when ('/', {controller: 'HomeController', templateUrl: 'home / home.view.html', controllerAs: 'vm'}). når ( '/ login', {controller: 'LoginController', templateUrl: 'login / login.view.html', controllerAs: 'vm'}). ellers ({redirectTo: '/ login'});} kjør. $ inject = ['$ rootScope', '$ location', '$ http', '$ window']; funksjonskjøring ($ rootScope, $ location, $ http, $ window) {var userData = $ window.sessionStorage.getItem ('userData '); if (userData) {$ http.defaults.headers.common [' Authorization '] =' Basic '+ JSON.parse (userData) .authData;} $ rootScope. $ on (' $ locationChangeStart ', function (event , neste, nåværende) {var restrictedPage = $ .inArray ($ location.path (), ['/ login']) === -1; var loginIn = $ window.sessionStorage.getItem ('userData'); hvis ( restrictedPage &&! loginIn) {$ location.pat h ('/ login'); }}); }}) ();
Innloggingskomponenten består av to filer, login.controller.js, og login.view.html.
La oss se på den første:
Logg Inn
Brukernavn Brukernavn kreves Passord Passord kreves Innlogging
og den andre:
(funksjon () {'bruk streng'; kantet .module ('app') .controller ('LoginController', LoginController); LoginController. $ inject = ['$ location', '$ window', '$ http']; funksjon LoginController ($ location, $ window, $ http) {var vm = this; vm.login = login; (function initController () {$ window.localStorage.setItem ('token', '');}) (); funksjonspålogging () {$ http ({url: '// localhost: 8082 / login', metode: "POST", data: {'userName': vm.username, 'password': vm.password}}). deretter. (funksjon (respons) {if (respons.data) {var token = $ window.btoa (vm.username + ':' + vm.password); var userData = {userName: vm.username, authData: token} $ window .sessionStorage.setItem ('userData', JSON.stringify (userData)); $ http.defaults.headers.common ['Authorization'] = 'Basic' + token; $ location.path ('/');} annet { varsel ("Autentisering mislyktes.")}});};}}) ();
Kontrolleren vil påkalle REST-tjenesten ved å sende brukernavnet og passordet. Etter vellykket godkjenning vil den kode brukernavnet og passordet og lagre det kodede tokenet i øktlagring for fremtidig bruk.
I likhet med påloggingskomponenten består hjemmekomponenten også av to filer, home.view.html:
Du er logget inn !!
Logg ut
og home.controller.js:
(funksjon () {'bruk streng'; kantet .module ('app') .controller ('HomeController', HomeController); HomeController. $ inject = ['$ window', '$ http', '$ scope']; funksjon HomeController ($ vindu, $ http, $ omfang) {var vm = dette; vm.user = null; initController (); funksjon initController () {$ http ({url: '// localhost: 8082 / bruker', metode : "GET"}). Deretter (funksjon (respons) {vm.user = respons.data.navn;}, funksjon (feil) {console.log (feil);});}; $ scope.logout = funksjon ( ) {$ window.sessionStorage.setItem ('userData', ''); $ http.defaults.headers.common ['Authorization'] = 'Basic';}}}) ();
Hjemmekontrolleren vil be om brukerdata ved å sende Autorisasjon Overskrift. REST-tjenesten vår returnerer bare brukerdataene hvis symbolet er gyldig.
La oss nå installere http-server for å kjøre Angular-applikasjonen:
npm installer http-server - lagre
Når dette er installert, kan vi åpne prosjektets rotmappe i ledeteksten og utføre kommandoen:
http-server -o
4.2. Bruke Angular versjon 2, 4, 5
De index.html i versjon 2 skiller seg noe fra AngularJS-versjonen:
System.import ('app'). Fangst (funksjon (err) {console.error (err);}); Laster inn ...
De main.ts er hovedinngangsstedet for søknaden. Det bootstraps applikasjonsmodulen og som et resultat laster nettleseren påloggingssiden:
platformBrowserDynamic (). bootstrapModule (AppModule);
De app.routing.ts er ansvarlig for applikasjonsrutingen:
const appRoutes: Routes = [{path: '', component: HomeComponent}, {path: 'login', component: LoginComponent}, {path: '**', redirectTo: ''}]; eksport const routing = RouterModule.forRoot (appRoutes);
De app.module.ts erklærer komponentene og importerer de aktuelle modulene:
@NgModule ({importerer: [BrowserModule, FormsModule, HttpModule, routing], erklæringer: [AppComponent, HomeComponent, LoginComponent], bootstrap: [AppComponent]}) eksportklasse AppModule {}
Siden vi oppretter en enkeltsidesapp, la oss lage en rotkomponent som legger til alle underordnede komponenter i den:
@Component ({selector: 'app-root', templateUrl: './app.component.html'}) eksportklasse AppComponent {}
De app.component.html vil bare ha en stikkord. The Angular bruker denne koden for sin lokaliseringsmekanisme.
La oss nå opprette påloggingskomponenten og dens tilhørende mal i login.component.ts:
@Component ({selector: 'login', templateUrl: './app/login/login.component.html'}) eksportklasse LoginComponent implementerer OnInit {model: any = {}; konstruktør (privat rute: ActivatedRoute, privat ruter: Ruter, privat http: Http) {} ngOnInit () {sessionStorage.setItem ('token', ''); } logg inn () {let url = '// localhost: 8082 / login'; la resultat = dette.http.post (url, {brukernavn: dette.modell.brukernavn, passord: dette.modell.passord}). kart (res => res.json ()). abonner (isValid => {if ( isValid) {sessionStorage.setItem ('token', btoa (this.model.username + ':' + this.model.password)); this.router.navigate (['']);} else {alert ("Authentication mislyktes. ");}}); }}
Til slutt, la oss ta en titt på login.component.html:
Brukernavn Brukernavn kreves Passord Passord kreves Innlogging
4.3. Bruke vinkel 6
Angular-teamet har gjort noen forbedringer i versjon 6. På grunn av disse endringene vil eksemplet vårt også være litt annerledes enn andre versjoner. Den eneste endringen vi har i vårt eksempel med hensyn til versjon 6, er i tjenesteanropsdelen.
I stedet for HttpModule, versjonen 6 importerer HttpClientModule fra@ vinkel / vanlig / http.
Serviceanropsdelen vil også være litt forskjellig fra eldre versjoner:
denne.http.post(url, {userName: this.model.username, password: this.model.password}). abonner (isValid => {if (isValid) {sessionStorage.setItem ('token', btoa (this.model.username + ') : '+ this.model.password)); this.router.navigate ([' ']);} else {alert ("Autentisering mislyktes.")}});
5. Konklusjon
Vi har lært hvordan vi implementerer en Spring Security-påloggingsside med Angular. Fra versjon 4 og utover kan vi bruke Angular CLI-prosjektet for enkel utvikling og testing.
Som alltid kan alt eksemplet vi har diskutert her bli funnet over GitHub-prosjektet.