WebApi Owin Authentication с Angular 2 работает только на локальном хосте
У меня есть реализация для аутентификации токенов на предъявителя owin, которая отлично работает на локальном хосте. (Локально). Но когда я размещаю приложение на iis, метод Authorize не заполняет access_token и не добавляет его к URL-адресу (как это происходит локально).
Есть ли у вас какие-либо идеи?? Мой код:
WebApiConfig
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Use camel case for JSON data.
//config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// Make Newtonsoft.Json default json serializer
var formatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault();
if (formatter != null)
{
formatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
}
Startup.Auth
// Enable the application to use OAuthAuthorization. You can then secure your Web APIs
static Startup()
{
PublicClientId = "web";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
AuthorizeEndpointPath = new PathString("/Account/Authorize"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true,
};
}
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
private static void ApplyRedirect(CookieApplyRedirectContext context)
{
Uri absoluteUri;
if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out absoluteUri))
{
var path = PathString.FromUriComponent(absoluteUri);
if (path == context.OwinContext.Request.PathBase + context.Options.LoginPath)
{
#if DEBUG
context.RedirectUri = "http://localhost:34000/authentication/login";
#else
context.RedirectUri = "https://sigma.cmtrading.com/authentication/login";
#endif
}
}
context.Response.Redirect(context.RedirectUri);
}
// For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(DbLoader.GetDb);
app.CreatePerOwinContext<SigmaUserManager>(SigmaUserManager.Create);
app.CreatePerOwinContext<SigmaSignInManager>(SigmaSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Authentication/Login"),
LogoutPath = new PathString("/Authentication/Logout"),
Provider = new CookieAuthenticationProvider
{
// Applying redirect to api domain
OnApplyRedirect = ApplyRedirect,
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<SigmaUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(20),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
// Enables the application to remember the second login verification factor such as phone or email.
// Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
// This is similar to the RememberMe option when you log in.
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
Угловая аутентификация.сервис:
private gateway = `${environment.baseHref}/api/Authentication`;
constructor(private router: Router,
private http: Http) { }
public GetCurrentUser(): Observable<SystemUser> {
let headers = new Headers();
headers.append('Authorization', `Bearer ${this.getAccessToken()}`);
return this.http.get(this.gateway, { headers: headers })
.map(res => {
if (!res.json().IsSuccess)
console.log(res.json().ErrorMessage);
console.log('here now');
console.log(this.getAccessToken());
return res.json().Data;
});
}
public Logout(): Promise<void> {
sessionStorage.removeItem('accessToken');
return this.http.post(`${this.gateway}/Logout`, [])
.toPromise()
.then(() => this.redirectToLogin());
}
private redirectToLogin() {
this.router.navigate(['/authentication/login']);
}
public async login(username: string, password: string, rememberMe: boolean):
Promise<boolean> {
return this.http.post(`${this.gateway}/Login`, { UserName: username,
Password: password, RememberMe: rememberMe })
.toPromise()
.then
(
resolve => {
if (!resolve.json().IsSuccess)
console.log(resolve.json().ErrorMessage);
return resolve.json().IsSuccess;
});
}
public async register(model: RegistrationModel): Promise<{ isSuccess: boolean, ErrorMessage: any }> {
return this.http.put(`${this.gateway}/Register`,
{
UserName: model.UserName,
Email: model.Email,
Password: model.Password,
ConfirmPassword: model.ConfirmPassword,
FullName: model.FullName
})
.toPromise()
.then
(
resolve => {
return { isSuccess: resolve.json().IsSuccess, ErrorMessage:
resolve.json().ErrorMessage }
});
}
public isAuthenticated(): boolean {
if (this.getAccessToken()) {
return true;
}
else
{
// The following code looks for a fragment in the URL to get the
access token which will be
// used to call the protected Web API resource
var fragment = urlFragmenter.getFragment();
if (fragment.access_token) {
console.log('setting');
// returning with access token, restore old hash, or at least hide token
window.location.hash = fragment.state || '';
this.setAccessToken(fragment.access_token);
return true;
}
else
{
// no token - so bounce to Authorize endpoint in AccountController to sign in or register
let url = `${environment.baseHref}/Account/Authorize?client_id=web&response_type=token&state=` + encodeURIComponent(window.location.hash);
window.location.href = url;
this.router.navigate([url]);
return false;
}
}
}
private setAccessToken(accessToken: string): void {
sessionStorage.setItem("accessToken", accessToken);
};
public getAccessToken(): string {
return sessionStorage.getItem("accessToken");
};
}
class urlFragmenter {
public static getFragment(): any {
console.log(window.location);
console.log(window.location.hash);
// NOT working on production !!!!
if (window.location.hash.indexOf("#") === 0) {
console.log('this is the index');
console.log(window.location.hash.substr(1));
return this.parseQueryString(window.location.hash.substr(1));
} else {
return {};
}
}
private static parseQueryString(queryString) {
console.log('parsing');
var data = {},
pairs, pair, separatorIndex, escapedKey, escapedValue, key, value;
if (queryString === null) {
return data;
}
pairs = queryString.split("&");
for (var i = 0; i < pairs.length; i++) {
pair = pairs[i];
separatorIndex = pair.indexOf("=");
if (separatorIndex === -1) {
escapedKey = pair;
escapedValue = null;
} else {
escapedKey = pair.substr(0, separatorIndex);
escapedValue = pair.substr(separatorIndex + 1);
}
key = decodeURIComponent(escapedKey);
value = decodeURIComponent(escapedValue);
data[key] = value;
}
return data;
}