Заголовок авторизации не работает для angular 2

Здравствуйте, я использую фреймворк Ionic 2 с Angular и хочу сделать http-запрос с заголовком авторизации, но, похоже, он не отправляет заголовок. Что я сделал не так?

    @Injectable()
export class UserServiceProvider {
  private loginSuccess: any;
  constructor(public http: Http) {
    console.log('Hello UserServiceProvider Provider');
  }

  login(username, password)
  {
     var token = btoa(username + ':' + password);
     alert(token);
     this.loginSuccess = false;
     let headers = new Headers();
     headers.append('Authorization', 'Basic ' + token);
     this.http.get('http://localhost:8080/HelloWorld/api/login/try', {
         headers: headers
     })
     .subscribe(function success(response) {
        this.loginSuccess = true;
     }, function error(response) {
        this.loginSuccess = false;
     });

     return this.loginSuccess;
  }
}

Вот ответ в консоли браузера

polyfills.js:3 OPTIONS http://localhost:8080/HelloWorld/api/login/try 401 ()
s @ polyfills.js:3
t.scheduleTask @ polyfills.js:3
onScheduleTask @ polyfills.js:3
t.scheduleTask @ polyfills.js:3
r.scheduleTask @ polyfills.js:3
r.scheduleMacroTask @ polyfills.js:3
(anonymous) @ polyfills.js:3
o.(anonymous function) @ polyfills.js:2
(anonymous) @ http.es5.js:1275
Observable._trySubscribe @ Observable.js:171
Observable.subscribe @ Observable.js:159
webpackJsonp.197.UserServiceProvider.login @ user-service.ts:29
webpackJsonp.196.AccountPage.login @ account.ts:21
(anonymous) @ AccountPage.html:25
handleEvent @ core.es5.js:12022
callWithDebugContext @ core.es5.js:13486
debugHandleEvent @ core.es5.js:13074
dispatchEvent @ core.es5.js:8615
(anonymous) @ core.es5.js:9226
(anonymous) @ platform-browser.es5.js:2651
t.invokeTask @ polyfills.js:3
onInvokeTask @ core.es5.js:3881
t.invokeTask @ polyfills.js:3
r.runTask @ polyfills.js:3
e.invokeTask @ polyfills.js:3
p @ polyfills.js:2
v @ polyfills.js:2

(индекс): 1 Не удалось загрузить http://localhost:8080/HelloWorld/api/login/try: ответ на предварительную проверку имеет недопустимый код состояния HTTP 401.


person Daniel McCarthy    schedule 01.11.2017    source источник
comment
@Deniel McCarthy: прикрепите скриншот запроса, отправляемого на сервер. Еще один момент, похоже, вы выполняете вход в систему, если это так, то при входе в систему наиболее часто используется метод POST, а не GET.   -  person AddWeb Solution Pvt Ltd    schedule 01.11.2017
comment
Я добавил ответ на сообщение. Я не думаю, что POST или GET будут иметь значение. Это не HTML-форма, это Http Basic Authentication.   -  person Daniel McCarthy    schedule 01.11.2017
comment
Пожалуйста, проверьте проблему CORS, так как предварительная проверка не удалась.   -  person Prithivi Raj    schedule 01.11.2017
comment
@DanielMcCarthy Пожалуйста, проверьте мой отредактированный ответ, где я добавил метод фильтра для решения проблемы CORS.   -  person Prithivi Raj    schedule 01.11.2017
comment
Сообщение об ошибке, показанное в вопросе, предназначено для ответа на ОПЦИИ предварительной проверки CORS, которые браузер отправил автоматически самостоятельно, даже не попытавшись выполнить запрос GET из вашего кода. Протокол CORS требует, чтобы в предварительный запрос OPTIONS не включались учетные данные, поэтому браузер не отправлял заголовок авторизации из вашего кода. Но сервер, на который вы отправляете этот запрос, неправильно настроен и требует аутентификации даже для запросов OPTIONS. Таким образом, сервер отправляет ответ 401, отклоняя запрос, и предварительная проверка завершается неудачно, и браузер останавливается прямо здесь и никогда не пытается выполнить ваш GET.   -  person sideshowbarker    schedule 01.11.2017


Ответы (2)


Ниже приведен пример кода моего проекта, который я использую для входа в систему. Пожалуйста, обратитесь к тому же для входа в систему. пожалуйста, проверьте, является ли функция входа в веб-службу GET или POST.

public postOAuthRequest(login:Login):Promise<any> {
    // Parameters obj-

    let params:URLSearchParams = new URLSearchParams();
    let headersvar = new Headers();

    params.set('username', login.userId.toString());
    params.set('password', login.password.toString());
    params.set('grant_type', 'password');
    params.set('scope', 'read write');
    params.set('client_secret', '123456');
    params.set('client_id', 'prithivi');
    var authdata = 'Basic ' + btoa('clientapp' + ':' + '412589');

    headersvar.append('accept', 'application/json');
    headersvar.append('Authorization', authdata);

    let requestOption:RequestOptionsArgs = {
        search: params,
        headers: headersvar,
        body: JSON.stringify({clientapp: 412589})
    };


    return this.http
        .post(OauthUrl, JSON.stringify({clientapp: 412589}), requestOption)
        .toPromise()
        .then(this.extractData)
}

Добавьте метод фильтра CORS в веб-службу, чтобы решить проблему CORS. Ниже код находится в JAVA

 @Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT,DELETE");
        response.setHeader("Access-Control-Max-Age", "3628800");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, X-XSRF-TOKEN");
        if (!"OPTIONS".equals(request.getMethod())) {
            chain.doFilter(req, res);
        } else {
            response.setStatus(200);
        }
}
person Prithivi Raj    schedule 01.11.2017
comment
Спасибо. Где я могу переопределить doFIlter? В моем остальном контроллере? - person Daniel McCarthy; 01.11.2017
comment
создайте новый класс и реализуйте его с интерфейсом javax.servlet.filter. - person Prithivi Raj; 01.11.2017
comment
Итак, я могу реализовать фильтр в любом классе, который имеет сопоставление запросов? - person Daniel McCarthy; 01.11.2017
comment
Класс фильтра будет выполняться перед обслуживанием любого запроса, поэтому хорошо создать отдельный класс для фильтра. - person Prithivi Raj; 01.11.2017
comment
С какой проблемой вы столкнулись сейчас? - person Prithivi Raj; 02.11.2017
comment
я ответил на него прокрутите вниз до моего ответа - person Daniel McCarthy; 02.11.2017
comment
Моя репутация недостаточно высока, извините - person Daniel McCarthy; 02.11.2017

Притиви Радж помог решить мою проблему, но не полностью. я использовал его код

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT,DELETE");
        response.setHeader("Access-Control-Max-Age", "3628800");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, X-XSRF-TOKEN");
        if (!"OPTIONS".equals(request.getMethod())) {
            chain.doFilter(req, res);
        } else {
            response.setStatus(200);
        }
}

Вы должны создать фильтр, который реализует фильтр, а затем добавить в свой веб-XML

<filter>
     <filter-name>FilterName</filter-name>
        <filter-class>FilterPackage.FilterClass</filter-class>
</filter>
<filter-mapping>
    <filter-name>FilterName</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Наконец, я предполагаю, что используется базовая конфигурация безопасности, поэтому в вашем WebSecurityConfigurerAdapter ваш метод настройки должен выглядеть так, как показано ниже. В основном вы добавляете фильтр до того, как BasicAuthenticationFilter активируется, решая проблему. Если вы этого не сделаете и ваша страница входа использует аутентификацию, то ваш фильтр будет вызываться только после аутентификации, и к этому моменту будет уже слишком поздно.

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(new CorsFilter(), BasicAuthenticationFilter.class);
        http
                .authorizeRequests()
                .antMatchers("/api/login/try").access("hasRole('ROLE_USER')")
                .antMatchers("/api/vehicles/manage/update").access("hasRole('ROLE_USER')")
                .antMatchers("/api/vehicles/manage/create").access("hasRole('ROLE_USER')")
                .antMatchers("/api/proposals/create").access("hasRole('ROLE_USER')")
                .antMatchers("/api/proposals/cancel").access("hasRole('ROLE_USER')")
                .antMatchers("/api/proposals/update").access("hasRole('ROLE_USER')")
                .antMatchers("/api/proposals/accept").access("hasRole('ROLE_USER')")
                .antMatchers("/api/upload").access("hasRole('ROLE_USER')")
                .anyRequest().permitAll()
                .and()
                .csrf().disable()
                .httpBasic()
                .and()
                .logout()
                .permitAll();

    }

Спасибо Притхиви Радж за вашу помощь!

person Daniel McCarthy    schedule 01.11.2017