在登录时添加授权标头,并使所有服务调用均可与此标头一起使用

时间:2018-07-06 10:09:49

标签: angular typescript spring-security

我正在尝试在登录时添加授权标头,并使该标头可用于请求所有其他服务调用。我的后端服务是在春季。

SecurityConfig:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/**").hasAnyRole(new String[] { "ADMIN" }).and().formLogin().loginPage("/login.html").permitAll().and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll();
    http.requiresChannel().anyRequest().requiresSecure();
    http.httpBasic();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).invalidSessionUrl("/");
    http.authorizeRequests().anyRequest().authenticated();
    http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}

UserService:

@RequestMapping(value = "/users/logged-in-user", method = RequestMethod.GET, produces = "application/json", consumes = "application/json")
public Object getCurrentLoggedInUser(){
    return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}

login.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { NgForm } from '@angular/forms';
import { LoginService } from './login.service';
import {HttpResponse} from "@angular/common/http";

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {

  constructor(private loginService: LoginService, private route: ActivatedRoute, private router: Router) { }

  public isLoginError: boolean = false;

  ngOnInit() {
    sessionStorage.removeItem('isUserLoggedIn');
  }

  public login(loginForm: NgForm) {
      this.loginService.login(loginForm.value).subscribe(res => { if(res.status === 200){ sessionStorage.setItem('isUserLoggedIn', 'YES'); this.router.navigateByUrl('app-root/home'); } }, err => { this.isLoginError = true; });
  }

}

login.service.ts:

import { Injectable } from '@angular/core';
import {HttpClient, HttpHeaders, HttpParams, HttpResponse} from '@angular/common/http';
import {Observable} from "rxjs/Observable";

@Injectable()
export class LoginService {

  constructor(private http: HttpClient) {
  }

  public login(loginData) : Observable<HttpResponse<any>> {
    console.log(loginData.username);
    console.log(loginData.password);
    console.log(btoa(loginData.username + ':' + loginData.password));
    return this.http.get<HttpResponse<any>>('/users/logged-in-user', { observe: 'response', headers: new HttpHeaders().set('Authorization', 'Basic ' + btoa(loginData.username + ':' + loginData.password)).set('Content-Type', 'application/json' ) } );
   }

}

login-guard.service.ts:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
import 'rxjs/add/operator/map';
import {HttpClient} from "@angular/common/http";

@Injectable()
export class LoginGuardService implements CanActivate {

  constructor(private router: Router, private http: HttpClient) { }

  public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
      if (sessionStorage.getItem('isUserLoggedIn')) {
          return true;
      } else {
          this.router.navigateByUrl('login');
          return false;
      }
  }

}

login-interceptor.service.ts:

import { Injectable } from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse, HttpResponse} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import {Router} from "@angular/router";

@Injectable()
export class LoginInterceptorService implements HttpInterceptor {

    constructor(private router: Router){
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const xhr = request.clone({
            headers: request.headers.set('X-Requested-With', 'XMLHttpRequest')
        });
        return next.handle(xhr).do((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // do stuff with response if you want
            }
        }, (err: any) => {
            if (err instanceof HttpErrorResponse) {
                if (err.status === 401) {
                    this.router.navigateByUrl('login');
                }
            }
        });
    }

}

app.routing.ts:

import { ModuleWithProviders } from '@angular/core/src/metadata/ng_module';
import { Routes, RouterModule } from '@angular/router';

import { LoginGuardService } from './login-guard.service';
import { FirstBootGuardService } from './first-boot-guard.service';
import { FirstBootComponent } from './first-boot/first-boot.component';
import { LoginComponent } from './login/login.component';
import { LogoutComponent } from './logout/logout.component';
import { AppRootComponent } from './app-root/app-root.component';
import { HomeComponent } from './home/home.component';
import { EndpointComponent } from './endpoint/endpoint.component';
import { FaultComponent } from './fault/fault.component';
import { TestsComponent } from './tests/tests.component';
import { TestsWithFaultComponent } from './tests-with-fault/tests-with-fault.component';
import { ReportsComponent } from './reports/reports.component';
import { SettingsComponent } from './settings/settings.component';

export const ROUTES: Routes = [
    { path: '', redirectTo: 'app-root/home', pathMatch: 'full' },
    { path: 'first-boot', component: FirstBootComponent },
    { path: 'login', component: LoginComponent },
    {
        path: 'app-root',
        component: AppRootComponent,
        canActivate: [ LoginGuardService ],
        children: [
            { path: 'home', component: HomeComponent },
            { path: 'endpoint', component: EndpointComponent },
            { path: 'fault', component: FaultComponent },
            { path: 'tests', component: TestsComponent },
            { path: 'tests-with-fault', component: TestsWithFaultComponent },
            { path: 'reports', component: ReportsComponent },
            { path: 'settings', component: SettingsComponent },
            { path: 'logout', component: LogoutComponent }
        ]
    }
];

export const ROUTING: ModuleWithProviders = RouterModule.forRoot(ROUTES);

app.module.ts:

import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
import { ClarityModule } from '@clr/angular';
import { AppComponent } from './app.component';
import { ROUTING } from "./app.routing";
import { FirstBootModule } from './first-boot/first-boot.module';
import { LoginModule } from './login/login.module';
import { LogoutModule } from './logout/logout.module';
import { AppRootModule } from './app-root/app-root.module';
import { HomeModule } from './home/home.module';
import { EndpointModule } from './endpoint/endpoint.module';
import { FaultModule } from './fault/fault.module';
import { TestsModule } from './tests/tests.module';
import { TestsWithFaultModule } from './tests-with-fault/tests-with-fault.module';
import { ReportsModule } from './reports/reports.module';
import { SettingsModule } from './settings/settings.module';
import { LoginGuardService } from './login-guard.service';
import { FirstBootGuardService } from './first-boot-guard.service';
import {LoginInterceptorService} from "./login-interceptor.service";

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserAnimationsModule,
        BrowserModule,
        FormsModule,
        HttpModule,
        HttpClientModule,
        ClarityModule,
        ROUTING,
        FirstBootModule,
        LoginModule,
        LogoutModule,
        AppRootModule,
        HomeModule,
        EndpointModule,
        FaultModule,
        TestsModule,
        TestsWithFaultModule,
        ReportsModule,
        SettingsModule
    ],
    providers: [LoginGuardService, FirstBootGuardService, { provide: HTTP_INTERCEPTORS, useClass: LoginInterceptorService, multi: true }],
    bootstrap: [AppComponent]
})
export class AppModule {
}

endpoint.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import {Observable} from "rxjs/Observable";

@Injectable()
export class EndpointService {
   //it works but need to be removed
   //public headers: HttpHeaders;

  constructor(private http: HttpClient) {
      //it works but need to be removed
      //this.headers = new HttpHeaders().set('Authorization', 'Basic YWRtaW46YWRtaW4=');
  }

  public getAllEndpoints() : Observable<any> {
      return this.http.get('/endpoints');
      //it works but need to be removed
      //return this.http.get('/endpoints', { headers: this.headers } );
  }

}

我能够登陆主页。我能够提出所有请求,并在设置HttpHeaders Authorization部分时得到响应。当我对每个请求禁用HttpHeaders Authorization部分时,就会出现问题。我的主要问题是:登录后我无法执行任何GET / POST / PUT等请求。即使登录后,我也必须在每个请求中添加HttpHeaders。我想在每个请求中删除HttpHeaders的设置。看来我已经很接近了,但是无法找出错误。在同一职位上回答将非常有帮助。预先感谢!

enter image description here

我的角度应用程序也配置了proxy.config文件,我观察到它不是401状态代码,而是302。

0 个答案:

没有答案