Я пытаюсь выполнить вход (Angular2 - клиент и веб-API 2 - на сервере).
Я получаю
ОПЦИИ http://localhost:48604/Token 400 (неверный запрос)
с последующим
Не удалось загрузить http://localhost:48604/Token: Ответ на запрос предварительной проверки не проходит проверку контроля доступа: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Происхождение 'http://localhost:4200' поэтому не разрешено. Ответ имеет HTTP-код состояния 400.
, в то время как другие запросы не срабатывают из-за проблемы CORS, потому что у меня CORS включен глобально в WebApiConfig.cs :
Веб-API:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
EnableCorsAttribute cors = new EnableCorsAttribute("http://localhost:4200", "*", "*");
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
My Startup.Auth.cs :
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
// ... Code for third-part logins omitted for brevity ...
}
}
Мой угловой сервис:
export class AuthService {
rootUrl = 'http://localhost:48604';
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded'
})
};
constructor(private httpClient: HttpClient) {
}
logIn(loginData): Observable<any> {
const data = 'grant_type=password&username=' + loginData.username + '&password=' + loginData.password;
return this.httpClient.post(this.rootUrl + '/Token', data, this.httpOptions);
}
}
И, насколько я понимаю, после / Token запрос должен быть перенаправлен на api / Account / ExternalLogin , но никогда не попадает в этот метод контроллера.
Затем я нашел сообщение , где они говорят, что вам нужно переопределить MatchEndpoint метод в ApplicationOAuthProvider классе, и я сделал это:
public override Task MatchEndpoint(OAuthMatchEndpointContext context)
{
if (context.IsTokenEndpoint && context.Request.Method == "OPTIONS")
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:4200" });
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "authorization"});
context.RequestCompleted();
return Task.FromResult(0);
}
return base.MatchEndpoint(context);
}
в моем компоненте входа:
this.authService.logIn(loginData).subscribe(
(data) => {
console.log(data);
//sessionStorage.setItem('tokenKey', token);
//console.log('sessionStorage.getItem: ' + sessionStorage.getItem('tokenKey'));
},
);
теперь я отвечаю на запрос POST 200 OK, но консоль все еще говорит:
Не удалось загрузить http://localhost:48604/Token: Нет заголовка «Access-Control-Allow-Origin» на запрошенном ресурсе. Origin 'http://localhost:4200' поэтому не допускается.
затем я добавляю еще один, если для метода POST, где я также добавляю необходимые заголовки:
public override Task MatchEndpoint(OAuthMatchEndpointContext context)
{
if (context.IsTokenEndpoint && context.Request.Method == "OPTIONS")
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin",
new[] {"http://localhost:4200"});
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] {"authorization"});
context.RequestCompleted();
return Task.FromResult(0);
}
if (context.IsTokenEndpoint && context.Request.Method == "POST")
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:4200" });
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "authorization", "Content-Type" });
context.RequestCompleted();
return Task.FromResult(0);
}
return base.MatchEndpoint(context);
}
Теперь метод POST будет добавлять заголовки к ответу.
но вместо токена я получаю ноль.