XMLHttpRequest error in .Net core 3.0 and angulr8,Access to XMLHttpRequest at url from from origin 'https://. has been blocked by CORS policy - angular8

I am trying to call SignIn in angular.
Login(reqobj: { RedirectUrl: string; }) {
var Url = this.GeturlFromServerName(this.baseUrl) + "Account/SignIn";this.baseUrl+reqobj.RedirectUrl;
return this.http.get(Url, {
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Accept': 'application/json; charset=utf-8',
"Access-Control-Allow-Origin": "*"
} })
}
Controller
[EnableCors("CorsPolicy")]
[AllowAnonymous]
[HttpGet, Route("SignIn")]
public async Task SignIn(string redirectUri)
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
try
{
await HttpContext.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties() { RedirectUri = redirectUri });
}
catch (Exception e)
{
_loggWriter.LogError("Login Exception :", e);
}
}
}
Startup.cs
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(o =>
{
o.ClientId = clientId;
o.ResponseType = "id_token";
o.GetClaimsFromUserInfoEndpoint = true;
o.MetadataAddress = metadataAddress;
o.SignedOutRedirectUri = PostLogoutRedirectUri;
o.Events = new OpenIdConnectEvents
{
OnRemoteFailure = OnAuthenticationFailed
};
});
services.AddAuthorization();
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.WithOrigins("https://localhost:44381", "https://sts.xxxxxx.com")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials());
});
private Task OnAuthenticationFailed(RemoteFailureContext arg)
{
arg.HandleResponse();
arg.Response.Redirect("/?errormessage=" + arg.Failure.Message);
return Task.FromResult(0);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseRouting();
app.UseFileServer();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
spa.UseAngularCliServer(npmScript: "start");
});
}
Getting Error Some thing like this
Access to XMLHttpRequest at 'https://.. from origin 'https://localhost:44381' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested

Related

Axios callback not logging value

I'm making a post request to the Spotify API, and it seems to work fine, but nothing is being returned from the callback. Any ideas?
const spotifyReq = async () => {
try {
await axios.post(
"https://accounts.spotify.com/api/token", "grant_type=client_credentials", {
headers: {
'Authorization': 'Basic' + (Buffer.from(client + ':' + secret, 'base64')),
'Content-Type' : 'application/x-www-form-urlencoded'
},
auth: {
username: "client",
password: "secret"
}
}, (res) => {
console.log(res)
})
} catch (err) {
if (err.request) {
console.log(err.response.data)
} else if (err.response) {
console.log(err.response.data)
} else {
console.log(err)
}
}
}

NextAuth authentication not working on Deployment on Vercel (Working on localhost)

Used credentials for authentication with nextauth. My code is not working on vercel deployment but working on localhost.
I used the basic cresdentials for authentication username and password but not able to get the session object after signing up from SignUpPage from the pages folder
[...nextauth].js
export default NextAuth({
session: {
jwt: true,
},
providers: [
Credentials({
async authorize(credentials) {
const client = await MongoClient.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const usersCollection = client.db().collection("users");
const user = await usersCollection.findOne({
username: credentials.username,
});
if (!user) {
client.close();
throw new Error("No user found!");
}
const isValid = await compare(credentials.password, user.password);
if (!isValid) {
client.close();
throw new Error("Could not log you in!");
}
client.close();
return { username: user.username };
},
}),
],
callbacks: {
jwt: async ({ token, user }) => {
if (user) {
token.user = user;
}
return token;
},
session: async ({ session, token }) => {
if (token) {
session.user = token.user;
}
return session;
},
},
secret: process.env.SECRET,
jwt: {
secret: process.env.SECRET,
encryption: true,
},
});
pages/api/auth/signup.js
async function handler(req, res) {
if (req.method !== "POST") {
return;
}
const data = req.body;
const { username, password } = data;
if (!username || !password || password.trim().length < 7) {
res.status(422).json({
message:
"Invalid input - password should also be at least 7 characters long.",
});
return;
}
const client = await MongoClient.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const db = client.db();
const existingUser = await db
.collection("users")
.findOne({ username: username });
if (existingUser) {
res.status(422).json({ message: "User exists already!" });
client.close();
return;
}
const hashedPassword = await hash(password, 12);
const result = await db.collection("users").insertOne({
username: username,
password: hashedPassword,
});
res.status(201).json({ message: "Created user!" });
client.close();
}
export default handler;
pages/SignUpPage.js
useEffect(() => {
getSession().then((session) => {
if (session) {
router.push("/");
} else {
setIsLoading(false);
}
});
}, [router]);
if (isLoading) {
return <p>Loading...</p>;
}
const createUser = async (username, password) => {
const response = await fetch("/api/auth/signup", {
method: "POST",
body: JSON.stringify({ username, password }),
headers: {
"Content-Type": "application/json",
},
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || "Something went wrong!");
}
return data;
};
const submitHandle = async (username, password) => {
if (login) {
const result = await signIn("credentials", {
redirect: false,
username: username,
password: password,
});
if (!result.error) {
router.push("/");
}
} else {
try {
const result = await createUser(username, password);
console.log("result", result);
router.push("/");
} catch (error) {
console.log(error);
}
}
};
Looks like you have used environment variables. Make sure you have updated them with relevant values.
for example,
NEXTAUTH_URL=http://localhost:3000
to
NEXTAUTH_URL=https://youdomain.com

IdentityServer4 and ASP.NET Core5.0 Identity - Role based Authorization

I would like to use ASP.NET Core Identity and IdentityServer together and provide Role-based authorization.
3 projects in the solution:
ApplicationAPI
ApplicationWeb
IdentityServer
Statup.cs in API Client
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllers();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:5001";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("ApiScope", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("scope", "api1");
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers()
.RequireAuthorization("ApiScope");
});
}
}
Startup.cs in MVC Client
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Authority = "https://localhost:5001";
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.Scope.Add("email");
options.Scope.Add("roles");
options.ClaimActions.DeleteClaim("sid");
options.ClaimActions.DeleteClaim("idp");
options.ClaimActions.DeleteClaim("s_hash");
options.ClaimActions.DeleteClaim("auth_time");
options.ClaimActions.MapJsonKey("role", "role");
options.Scope.Add("api1");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
services.AddTransient<AuthenticationDelegatingHandler>();
services.AddHttpClient("ApplicationAPI", client =>
{
client.BaseAddress = new Uri("https://localhost:5002/");
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
}).AddHttpMessageHandler<AuthenticationDelegatingHandler>();
services.AddHttpClient("ApplicationIdentityServer", client =>
{
client.BaseAddress = new Uri("https://localhost:5001/");
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
});
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{area=Admin}/{controller=Home}/{action=Index}/{id?}");
});
}
}
AuthenticationDelegatingHandler in MVC Application
To prevent getting token again.
public class AuthenticationDelegatingHandler : DelegatingHandler
{
private readonly IHttpContextAccessor _httpContextAccessor;
public AuthenticationDelegatingHandler(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);
if (!string.IsNullOrWhiteSpace(accessToken))
{
request.SetBearerToken(accessToken);
}
return await base.SendAsync(request, cancellationToken);
}
}
Config.cs in IdentityServer
public static class Config
{
public static IEnumerable<IdentityResource> IdentityResources =>
new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
new IdentityResource("roles", "Your role(s)", new List<string>() { "role" })
};
public static IEnumerable<ApiScope> ApiScopes =>
new List<ApiScope>
{
new ApiScope("api1", "My API")
};
public static IEnumerable<Client> Clients =>
// we can remove API client here because we call API from MVC
// and pass the token to API Application.
// Only we get token from IdentityServer with MVC Application
new List<Client>
{
new Client
{
ClientId = "client",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = { "api1" }
},
new Client
{
ClientId = "mvc",
ClientName = "Application Web",
AllowedGrantTypes = GrantTypes.Hybrid,
ClientSecrets = { new Secret("secret".Sha256()) },
RequirePkce = false,
AllowRememberConsent = false,
RedirectUris = { "https://localhost:5003/signin-oidc" },
PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"api1",
"roles"
}
}
};
}
I added ASP.NET Core Identity in the IdentityServer project
Startup.cs in IdentityServer
public class Startup
{
public IWebHostEnvironment Environment { get; }
public IConfiguration Configuration { get; }
public Startup(IWebHostEnvironment environment, IConfiguration configuration)
{
Environment = environment;
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
{
options.SignIn.RequireConfirmedEmail = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.EmitStaticAudienceClaim = true;
options.UserInteraction.LoginUrl = "/Account/Login";
options.UserInteraction.LogoutUrl = "/Account/Logout";
options.Authentication = new AuthenticationOptions()
{
CookieLifetime = TimeSpan.FromHours(10),
CookieSlidingExpiration = true
};
})
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients)
.AddAspNetIdentity<ApplicationUser>();
if (Environment.IsDevelopment())
{
builder.AddDeveloperSigningCredential();
}
services.AddAuthentication()
.AddGoogle(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "copy client ID from Google here";
options.ClientSecret = "copy client secret from Google here";
});
services.AddTransient<IEmailSender, EmailSender>();
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
Nuget Packages I used in IdentityServer project:
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="5.0.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.12" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.12">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.12" />
source code repo

How to add header to get request in vue js?

I am taking data from api, how to send get request with token after login?
It shows error createError.js?2d83:16 Uncaught (in promise) Error: Request failed with status code 401
export default new Vuex.Store({
state: {
users: []
},
mutations: {
setUsers(state, args){
state.users = args;
}
},
actions: {
login({ }, arg) {
axios.post('login/', { username: arg.username, password: arg.password })
.then((response) => {
console.log(response);
let accessToken = response.token.data;
localStorage.setItem('token', accessToken);
localStorage.setItem('user', response.data.user);
axios.defaults.headers.common['Authorization'] = accessToken;
window.isSignedIn = true;
router.push('/');
})
.catch((error) => {
console.log(error);
})
},
getUsers({ commit }){
let { data } = axios.get('v1/user/list/');
commit('setUsers', data);
}
}
})
Depends which authentication you are using. Try with:
axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
Other HTTP authentication schemes.

How to update view inside axios promise and after store dispatch?

I have a simple vue app where I'm trying to add simple authentication. Inside my login.vue, I use axios to authenticate the user via ajax and store the token returned by the api in the store then redirect to a new page (ex: dashboard.vue).
The problem is that the token is saved but the view is not updated, can't call router.push() ...
Any ideas why isn't it working ? Thanks
Login.vue
methods: {
authenticate () {
var dataLogin = {
email: this.login,
password: this.password
}
var headers = { headers: { 'Content-type': 'application/json', 'Accept': 'application/json' } }
axios.post(config.apiUrl, dataLogin, headers)
.then(response => {
this.$store.dispatch('login', response.data).then(() => {
// if there is no error go to home page
if (!this.$store.getters.error) {
this.$router.push('/')
}
})
})
.catch(error => {
this.errorMessage = error.response.data.message
this.authError = true
})
}
}
The store function just save the token with localStorage
const actions = {
login (context, data) {
context.commit('authenticate', data)
}
}
const mutations = {
authenticate (state, data) {
localStorage.setItem('user-access_token', data.access_token)
}
}
You are calling a then() handler when you dispatch the action.
But your action does not return a promise.
So return a promise in your action as follows:
const actions = {
login (context, data) {
return new Promise((resolve, reject) => {
context.commit('authenticate', data)
resolve()
})
}
}
Also chain your promises for better readability
axios.post(config.apiUrl, dataLogin, headers)
.then(response => {
return this.$store.dispatch('login', response.data)
}).then(() => {
// if there is no error go to home page
if (!this.$store.getters.error) {
this.$router.push('/')
}
})
.catch(error => {
this.errorMessage = error.response.data.message
this.authError = true
})