Я прошел через эту проблему и до сих пор не нашел ответа:
Мое приложение Angular отправляет кучу HTTP-запросов на asp.net. Asp.net обрабатывает запрос (проверка токена и т. Д.) И возвращает данные в порядке.
Дело в том, что в IIS я добавил сертификат SSL / TLS от Let's Encrypt, и приложение больше никогда не работало.
Странное поведение, которое я заметил
- Только логин метод работает. Все последующие запросы возвращают «Неизвестная ошибка - код состояния 0»
- Asp.net имеет перехватчик, который фильтрует каждый запрос на проверку токена. Если я отправляю заголовок авторизации, приложение не работает. Если я этого не сделаю, asp.net вернет ошибку 404 о том, что токен не существует в базе данных (как он должен)
- В Почтальоне запросы работают на 100% (даже проверка подлинности токена)
- Если я удаляю угловой перехватчик и промежуточное ПО в asp.net И удаляю сертификат SSL. приложение работает
- Chrome генерирует исключение "net :: ERR_SPDY_PROTOCOL_ERROR".
Я пробыл над головой два дня и не нашел ответа. Посмотрел на StackOverflow, IIS foruns, Angular Foruns, .Net foruns ... Ничего
Вот код:
Угловой перехватчик
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Filtrar apenas pedidos feitos à API
if(req.url.match("\\api")) {
let newRequest = req.clone({
headers: new HttpHeaders({
'Content-Type':'application/json',
'Authorization':this.cookieService.get('at')
})
});
return next.handle(newRequest);
} else {
return next.handle(req);
}
}
Asp.NET Middleware
public Task Invoke(HttpContext context) {
// Check if request is redirected to ".../api/exemplo/xyx"
// To exclude the 'login' request
if (context.Request.Path.Value.StartsWith("/api")) {
// Check if request is NOT an OPTIONS
if(!context.Request.Method.Equals("OPTIONS")){
// Check for header
string auth = context.Request.Headers["Authorization"].ToString();
FbConnectionStringBuilder csb = new FbConnectionStringBuilder {
DataSource = _appSettings.DataSource,
Port = _appSettings.Port,
Database = _appSettings.Database,
UserID = _appSettings.UserID,
Password = _appSettings.Password,
ServerType = FbServerType.Default
};
// Open db
FbConnection db = new FbConnection(csb.ToString());
db.Open();
// Get the expiration date of token
string query = "SELECT DT_REVOG FROM ORGANIG_TOKEN WHERE TOKEN = @auth";
DateTime now = DateTime.UtcNow;
DateTime DateRevogToken;
try
{
DateRevogToken = db.QuerySingle<DateTime>(query, new { auth });
db.Close();
if (now >= DateRevogToken)
{
// Expired
string deleteQuery = "DELETE FROM ORGANIG_TOKEN WHERE TOKEN = @auth";
db.Execute(deleteQuery, new { auth });
context.Response.StatusCode = 401;
context.Response.WriteAsync("A token não é válida");
return Task.CompletedTask;
}
else
{
// Is valid
return _next(context);
}
} catch(Exception e) {
context.Response.StatusCode = 404;
context.Response.WriteAsync("Ocorreu um erro na verificação da token: " + e.Message);
return Task.CompletedTask;
}
}
else {
//It's a OPTIONS request. Ignore
return _next(context);
}
}
else {
// Login request. Ignore
return _next(context);
}
}
}
Запрос на вход в систему (asp.net)
[Route("auth/gerar_token")]
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> GerarToken([FromBody] Client c)
{
// Conexão á base de dados Firebird
FbConnectionStringBuilder csb = new FbConnectionStringBuilder
{
DataSource = _appSettings.DataSource,
Port = _appSettings.Port,
Database = _appSettings.Database,
UserID = _appSettings.UserID,
Password = _appSettings.Password,
ServerType = FbServerType.Default
};
Client client = new Client();
string login = c.login;
string pass = c.pass;
string hashedPass = null;
string responseMessage;
// Hash da password do client
using (MD5 md5Hash = MD5.Create()) { hashedPass = GetMd5Hash(md5Hash, pass); }
using (var db = new FbConnection(csb.ToString())) {
string token;
try {
await db.OpenAsync();
// Query de login
string sql = @"SELECT CD, NOME, RAMO_ACT, DESIGN, EMAIL, LOGIN, MORAD
FROM ORGANIG WHERE LOGIN = @login AND PASS = @hashedPass";
client = await db.QuerySingleAsync<Client>(sql, new { login, hashedPass });
try {
int cd_organig = client.cd;
token = GenerateRefreshToken();
DateTime dt_cria = DateTime.UtcNow;
DateTime dt_revog = dt_cria.AddHours(4);
DateTime dt_inicio = DateTime.UtcNow;
string sql_token = @"INSERT INTO ORGANIG_TOKEN(TOKEN, CD_ORGANIG, DT_CRIA, DT_REVOG) VALUES (@token, @cd_organig, @dt_cria, @dt_revog)";
db.Execute(sql_token, new { token, cd_organig, dt_cria, dt_revog });
string sql_sessao = @"INSERT INTO ORGANIG_SESSAO(CD_ORGANIG, DT_INICIO, TOKEN, DT_REVOG_TOKEN) VALUES (@cd_organig, @dt_inicio, @token, @dt_revog)";
db.Execute(sql_sessao, new { cd_organig, dt_inicio, token, dt_revog });
}
catch (Exception e) {
JObject serverErroResponse = new JObject {
{ "Ocorreu um erro no servidor. Detalhes: ", e.Message }
};
db.Close();
return StatusCode(500, serverErroResponse);
}
JObject response = new JObject {
{ "token", token },
{ "cd", client.cd },
{ "nome", client.nome }
};
db.Close();
return Ok(response);
}
catch (Exception e) {
if(e.Message.Equals("Sequence contains no elements")) {
responseMessage = "Credenciais inválidas. Por favor, tente novamente";
} else {
responseMessage = "Ocorreu um erro no servidor. Detalhes: " + e.Message;
}
JObject serverErrorResponse = new JObject {
{ "message", responseMessage }
};
db.Close();
return StatusCode(500, serverErrorResponse);
}
} // using (var db = new FbConnection(csb.ToString()))
}
Пример запроса, который не работает
[Route("api/build_organig/{cd}")]
[HttpGet]
public IActionResult BuildOrganig(int cd)
{
// Conexão á base de dados Firebird
FbConnectionStringBuilder csb = new FbConnectionStringBuilder {
DataSource = _appSettings.DataSource,
Port = _appSettings.Port,
Database = _appSettings.Database,
UserID = _appSettings.UserID,
Password = _appSettings.Password,
ServerType = FbServerType.Default
};
// Abrir conexão á base de dados
FbConnection db = new FbConnection(csb.ToString());
db.Open();
// Query para retornar os dados do procedure para uma lista
List<BuildOrganig> buildOrganigList = new List<BuildOrganig>();
buildOrganigList = db.Query<BuildOrganig>("SELECT CD, CD_BASE, NOME FROM BUILD_ORGANIG(@cd) ORDER BY NIVEL", new { cd }).ToList();
if (buildOrganigList.Count == 0) {
JObject emptyResponse = new JObject {
{ "count", buildOrganigList.Count },
{ "message", "Organigrama não existente" }
};
db.Close();
return StatusCode(404, emptyResponse);
}
db.Close();
return StatusCode(200, buildOrganigList);
}
Вот несколько скриншотов почтальона и браузера
![Postman login](https://i.stack.imgur.com/vSzpl.jpg)
![Postman request](https://i.stack.imgur.com/NUNR2.png)
![Postman when header is missing](https://i.stack.imgur.com/pCfZV.jpg)
![Platform with errors on console](https://i.stack.imgur.com/r8rSL.jpg)
![IIS config](https://i.stack.imgur.com/a35xJ.jpg)
Если вам нужна дополнительная информация, просто укажите в комментариях.
Спасибо