2017-01-11 100 views
1

我使用Angular2,Angular-cli,Spring Boot 1.4.0和jwt。當我登錄我的Angular2客戶端時,我無法獲得jwt令牌。Angular2 Spring Boot JWT缺少響應頭

我的安全配置是:

@Configuration 
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http.csrf().disable() // disable csrf for our requests. 
       .authorizeRequests() 
       .antMatchers("/").permitAll() 
       .antMatchers("/api/user/signup").permitAll() 
       .antMatchers(HttpMethod.POST, "/api/user/login").permitAll() 
       .anyRequest().authenticated() 
       .and() 
       // We filter the api/login requests 
       .addFilterBefore(new JWTLoginFilter("/api/user/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class) 
       // And filter other requests to check the presence of JWT in header 
       .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); 
       .permitAll().and().csrf().disable(); 
    } 
} 

我TokenAuthenticationService是:

public class TokenAuthenticationService { 

    private final long EXPIRATIONTIME = 1000 * 60 * 60 * 24 * 10; // 10 days 
    private final String secret = "ThisIsASecret"; 
    private final String tokenPrefix = "Bearer"; 
    private final String headerString = "Authorization"; 
    public void addAuthentication(HttpServletResponse response, String username) 
    { 
     // We generate a token now. 
     String JWT = Jwts.builder() 
        .setSubject(username) 
        .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME)) 
        .signWith(SignatureAlgorithm.HS512, secret) 
        .compact(); 
     response.addHeader("Access-Control-Allow-Origin", "*"); 
     response.setHeader(headerString, tokenPrefix + " "+ JWT); 
     response.getHeaderNames().stream() 
    .forEach(System.out::println); 
    } 
    } 

當我在郵遞員發送請求標誌,我收到的反應是這樣的: enter image description here

但我發送登錄請求我的Angular2應用程序我無法接收名爲「授權」自定義標題的響應標題。我的響應對象是這樣的: enter image description here

但我看瀏覽器控制檯我看到我的costum頭「授權」。 enter image description here

我Angular2代碼:

@Injectable() 
export class LoginService { 
    private authEvents: Subject<AuthEvent>; 
    private cred: AccountCredentials; 

    constructor(private http: JsonHttpService){ 
    this.authEvents = new Subject<AuthEvent>(); 
    this.cred = new AccountCredentials(); 
    } 


    login(email: string, password: string) { 
    this.cred.password = password; 
    this.cred.username = email; 
    return this.http.post('http://localhost:9090/api/user/login', this.cred) 
    .do((resp: Response) => { 
     localStorage.setItem('jwt', resp.headers.get('Authorization')); 
     this.authEvents.next(new DidLogin()); 
    }); 
    } 

    logout(): void { 
    localStorage.removeItem('jwt'); 
    this.authEvents.next(new DidLogout()); 
    } 

    isSignedIn(): boolean { 
    return localStorage.getItem('jwt') !== null; 
    } 
} 

export class DidLogin { 
} 
export class DidLogout { 
} 

export type AuthEvent = DidLogin | DidLogout; 

而且我JsonHttpService是:

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { 
    Http, 
    RequestOptionsArgs, 
    RequestOptions, 
    Response, 
    Headers 
} from '@angular/http'; 

const mergeAuthToken = (options: RequestOptionsArgs = {}) => { 
    let newOptions = new RequestOptions({}).merge(options); 
    let newHeaders = new Headers(newOptions.headers); 
    const jwt = localStorage.getItem('jwt'); 

    if (jwt && jwt !== 'null') { 
    newHeaders.set('Authorization', jwt); 
    } 
newHeaders.set('content-type', 'application/x-www-form-urlencoded; charset=utf-8'); 

    // newHeaders.set('Access-Control-Allow-Origin', '*'); 
    newOptions.headers = newHeaders; 
    return newOptions; 
}; 

@Injectable() 
export class JsonHttpService { 

    constructor(private http: Http) { } 


    get(url: string, options?: RequestOptionsArgs): Observable<Response> { 
    return this.http.get(url, mergeAuthToken(options)); 
    } 

    post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> { 
    return this.http.post(url, body, mergeAuthToken(options)); 
    } 

    put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> { 
    return this.http.put(url, body, mergeAuthToken(options)); 
    } 

    delete(url: string, options?: RequestOptionsArgs): Observable<Response> { 
    return this.http.delete(url, mergeAuthToken(options)); 
    } 

    patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> { 
    return this.http.patch(url, body, mergeAuthToken(options)); 
    } 

    head(url: string, options?: RequestOptionsArgs): Observable<Response> { 
    return this.http.head(url, mergeAuthToken(options)); 
    } 


} 

那麼,爲什麼我不能收到我的智威湯遜的令牌,並添加我的瀏覽器localStorage的?

回答

0

您是否正在運行Angular2應用程序和不同端口上的springboot?如果是這樣,你是否在你的springboot應用程序中啓用了CORS?

添加withCredentials: true您Angualr2後頭

this.http.post('http://localhost:9090/api/user/login', 
    { withCredentials: true }, 
    this.cred) 

更多springboot JWT工作,棱角分明,結賬Springboot JWT Starter

1

的瀏覽器不公開自定義頁眉到系統默認的應用程序。

你需要下面的頭在你的後端一個Cors配置

'Access-Control-Expose-Headers' 'Authorization'; 

注意,即使頭是目前在開發者控制檯中您的應用程序無法讀取它們,如果它們不是由你的服務器應用程序公開。

0

解決您的問題的最佳方法是在您的應用程序中添加cors配置,如https://spring.io/blog/2015/06/08/cors-support-in-spring-framework中所述。 你也可以這樣做:

@Configuration 
public class RestConfigs { 
    @Bean 
    public CorsFilter corsFilter() { 
     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
     CorsConfiguration config = new CorsConfiguration(); 
     config.setAllowCredentials(true); 
     config.addAllowedOrigin("*"); 
     config.addExposedHeader(MyUtils.AUTHENTICATION); //Header String 
     config.addAllowedHeader("*"); 
     config.addAllowedMethod("OPTIONS"); 
     config.addAllowedMethod("GET"); 
     config.addAllowedMethod("POST"); 
     config.addAllowedMethod("PUT"); 
     config.addAllowedMethod("DELETE"); 
     source.registerCorsConfiguration("/**", config); 
     return new CorsFilter(source); 
    } 
相關問題