Reputation: 601
I use identity server 4 with blazor server side client
everything is ok but token not authorized api methods but token works in server authorized controllers
is something wrong with grant type or code flow ?
server config class :
public static class Configurations
{
public static IEnumerable<IdentityResource> GetIdentityResources() =>
new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
public static IEnumerable<ApiResource> GetApis() =>
new List<ApiResource> {
new ApiResource("api1")
};
public static IEnumerable<ApiScope> GetApiScopes()
{
return new List<ApiScope>
{
// backward compat
new ApiScope("api1")
};
}
public static IEnumerable<Client> GetClients() => new List<Client>
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.Code,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = {
"api1" ,
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
},
RedirectUris = { "https://localhost:44372/signin-oidc" },
AlwaysIncludeUserClaimsInIdToken = true,
AllowOfflineAccess = true,
RequireConsent = false,
RequirePkce = true,
}
};
}
server start up class :
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(config =>
{
config.UseInMemoryDatabase("Memory");
});
// AddIdentity registers the services
services.AddIdentity<IdentityUser, IdentityRole>(config =>
{
config.Password.RequiredLength = 4;
config.Password.RequireDigit = false;
config.Password.RequireNonAlphanumeric = false;
config.Password.RequireUppercase = false;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(config =>
{
config.Cookie.Name = "IdentityServer.Cookie";
config.LoginPath = "/Auth/Login";
config.LogoutPath = "/Auth/Logout";
});
services.AddIdentityServer()
.AddAspNetIdentity<IdentityUser>()
//.AddInMemoryApiResources(Configurations.GetApis())
.AddInMemoryIdentityResources(Configurations.GetIdentityResources())
.AddInMemoryApiScopes(Configurations.GetApiScopes())
.AddInMemoryClients(Configurations.GetClients())
.AddDeveloperSigningCredential();
services.AddControllersWithViews();
}
api start up class :
services.AddAuthentication("Bearer").AddIdentityServerAuthentication(option =>
{
option.Authority = "https://localhost:44313";
option.RequireHttpsMetadata = false;
option.ApiName = "api1";
});
blazor server side start up class:
services.AddAuthentication(config =>
{
config.DefaultScheme = "Cookie";
config.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookie")
.AddOpenIdConnect("oidc", config =>
{
config.Authority = "https://localhost:44313/";
config.ClientId = "client";
config.ClientSecret = "secret";
config.SaveTokens = true;
config.ResponseType = "code";
config.SignedOutCallbackPath = "/";
config.Scope.Add("openid");
config.Scope.Add("api1");
config.Scope.Add("offline_access");
});
services.AddMvcCore(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser() // site-wide auth
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
Upvotes: 0
Views: 445
Reputation: 2394
To fix this issue, you have 2 options:
1- (Recommended) To add the scopes to API resource like this:
public static IEnumerable<ApiResource> GetApis() =>
new List<ApiResource> {
new ApiResource("api1")
{
Scopes = new []{ "api1" }
}
};
public static IEnumerable<ApiScope> GetApiScopes()
{
return new List<ApiScope>
{
// backward compat
new ApiScope("api1")
};
}
2- On API change your code to set ValidateAudience = false
, like this:
services.AddAuthentication("Bearer").AddJwtBearer("Bearer",
options =>
{
options.Authority = "http://localhost:5000";
options.Audience = "api1";
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new
TokenValidationParameters()
{
ValidateAudience = false
};
});
Here is my blog about migrating IdentityServer4 to v4 https://nahidfa.com/posts/migrating-identityserver4-to-v4/
Upvotes: 1
Reputation: 5461
I have not actually used AddIdentityServerAuthentication
in API but can you try the below code. Technically its same thing, but maybe this will work.
Change your api authentication from AddIdentityServerAuthentication
to AddJwtBearer
:
services.AddAuthentication("Bearer").AddIdentityServerAuthentication(option =>
{
option.Authority = "https://localhost:44313";
option.RequireHttpsMetadata = false;
option.ApiName = "api1";
});
to
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", option =>
{
option.Authority = "https://localhost:44313";
option.Audience = "api1";
option.SaveToken = true;
});
Upvotes: 0