#android-volley #asp.net-core-webapi #azure-ad-b2c
#android-volley #asp.net-core-webapi #azure-ad-b2c
Вопрос:
Я использую Volley для подключения к dot net core web api, защищенному Azure B2C. Проблема в том, что я получаю ответ HTML от API, что затрудняет идентификацию и разрешение в клиентском приложении.
Ответ, который я получаю, следующий:
HTML за ним:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><title>Logging in...</title><meta name='CACHE-CONTROL' content='NO-CACHE'/><meta name='PRAGMA' content='NO-CACHE'/><meta name='EXPIRES' content='-1'/></head><body><form id='auto' method='post' action='https://localhost:5001/signin-oidc'><div><input type='hidden' name='error' id='error' value='redirect_uri_mismatch'/><input type='hidden' name='error_description' id='error_description' value='AADB2C90006: The redirect URI amp;#39;https://dev.webapi.enablewear.com/signin-oidcamp;#39; provided in the request is not registered for the client id amp;#39;[guid here]amp;#39;.
Correlation ID: [guid here]
Timestamp: 2021-02-19 13:28:34Z
'/><input type='hidden' name='state' id='state' value='[token here]'/></div><div id='noJavascript' style='visibility: visible; font-family: Verdana'><p>Although we have detected that you have Javascript disabled, you will be able to use the site as normal.</p><p>As part of the authentication process this page may be displayed several times. Please use the continue button below.</p><input type='submit' value='Continue' /></div><script type='text/javascript'>
<!--
document.getElementById('noJavascript').innerHTML = ''; document.getElementById('auto').submit();
//--></script></form></body></html>
Единственный способ получить эту информацию — через Volley StringRequest:
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "onResponse: " response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "onErrorResponse: " error.toString());
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> param = new HashMap<>();
//param.put(IndicationDM.NAME, indication.getName());
return param;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> header = new HashMap<>();
Log.d(TAG, "getHeaders: Bearer " accessToken);
header.put("Authorization", "Bearer " accessToken);
return header;
}
};
Я бы предпочел использовать JsonObjectRequest и обрабатывать подобные ошибки:
if ( error instanceof AuthFailureError ) {
Log.d(TAG, "onError: AuthFailureError");
} else if (error instanceof NetworkError) {
Log.d(TAG, "onError: NetworkError");
} else if (error instanceof ParseError) {
Log.d(TAG, "onError: ParseError");
}
но проблема в том, что ошибка AuthFailureError не вызывается, ошибка ParseError вызвана тем, что приведенный выше HTML не является JSON. Я бы хотел, чтобы результат возвращался как json или запускал AuthFailureError, но я не уверен, есть ли конфигурация webapi, которую мне нужно изменить, или конфигурация Azure b2c.
Контроллер dotnet core webapi использует атрибут [Authorize]. Возможно, мне потребуется обновить токен, но я столкнусь с этой проблемой и захочу перехватить / ответить на нее.
Есть идеи?
Обновить
Я просмотрел этот пример и внес изменения в startup.cs и теперь получаю AuthFailureError, что здорово. Мне все еще невероятно сложно диагностировать проблемы, что является темой для другого сообщения. Вот что я изменил:
Для:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options =>
{
Configuration.Bind("AzureAdB2C", options);
options.TokenValidationParameters.NameClaimType = "name";
},
options => { Configuration.Bind("AzureAdB2C", options); });
services.AddControllers();
services.AddAuthorization();
От:
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C");
Я не могу с уверенностью сказать, что я больше ничего не менял. Я пытался внести изменения на сервере, но на самом деле это было последнее изменение, которое я помню, как делал / тестировал.
Ответ №1:
Я предполагаю, что «защищенный B2C» здесь означает, что он развернут в службе веб-приложений Azure с использованием Easy Auth, по-прежнему имеет место. Как только вы настроите службу приложений на требование проверки подлинности, она будет ожидать либо получения токена доступа в заголовке авторизации, либо файла cookie авторизации в запросе. Служба приложений не делает различий между размещением API или веб-приложения (html). Если он не получит токен доступа или файл cookie, он предположит, что браузер пытается получить доступ к веб-приложению, и инициирует перенаправление OIDC на сервер. Ваш клиент, вызывающий API, должен рассматривать ответ 302 как несанкционированный. Ваш веб-Api не должен использовать [Авторизовать] или пытаться проверять входящие токены. Служба Azure сделает это. Вы можете получить утверждения (и токен) в коде вашего приложения, используя переменные среды или ClaimsPrincipal в соответствии со статьей.
Комментарии:
1. Интересно. Не рассматривал это. Во многих примерах, которые я читал, использовался [Авторизовать] . Я смотрел на github.com/Azure-Samples /… и внес некоторые изменения в автозагрузку, и теперь я получаю ошибку AuthFailureError. Будет ли влияние, когда я попытаюсь перейти к более мелкозернистым областям. Также у меня возникают реальные проблемы с диагностикой проблем. Здорово, что я получаю сообщение об ошибке, но в журналах ничего не отображается.
2. Исправление: у вас может быть [Авторизовать] — это ничего не делает, поскольку все запросы должны быть авторизованы при использовании Easy Auth. Вы не должны использовать какую-либо обработку токенов при запуске, поскольку это обрабатывается самой службой веб-приложений Azure.