参考链接
- https://www.cnblogs.com/jaycewu/p/7791102.html 写的超级详细,代码一定要复制好
- mark 有时间再把整个测试环境搭好写上
1.创建环境
IdentityServer4环境搭建
下面的环境是基于VS Stuido环境测试
2.修改IdentityServer4配置文件
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
//new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
{
new ApiResource("api1","My Api")
};
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
///
ClientId = "client",
// 没有交互性用户,使用 客户端模式 进行身份验证。
//AllowedGrantTypes = GrantTypes.ClientCredentials,
//登录验证
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
// 用于认证的密码
ClientSecrets =
{
new Secret("123456789".Sha256())
},
// 客户端有权访问的范围(Scopes)
//AllowedScopes = { "api1" }
AllowedScopes = { "api1",IdentityServerConstants.StandardScopes.OpenId, //必须要添加,否则报forbidden错误
IdentityServerConstants.StandardScopes.Profile},
}
};
}
3.修改 Starp up文件。
注意,这边为了偷懒,将一些配置文件都放在这里面了。这个仅供测试使用
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//修改的
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.Apis)
.AddInMemoryIdentityResources(Config.Ids)
.AddInMemoryClients(Config.Clients)
.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
.AddProfileService<ProfileService>();
//services.AddIdentityServer()
// .AddDeveloperSigningCredential()
// .AddInMemoryIdentityResources(Config.GetIdentityResourceResources())
// .AddInMemoryApiResources(Config.GetApiResources())
// .AddInMemoryClients(Config.GetClients())
// .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
// .AddProfileService<ProfileService>();
//增加权限访问
services.AddAuthentication(config =>
{
config.DefaultScheme = "Bearer"; //这个是access_token的类型,获取access_token的时候返回参数中的token_type一致
}).AddIdentityServerAuthentication(option =>
{
option.ApiName = "api1"; //资源名称,认证服务注册的资源列表名称一致,
option.Authority = "http://localhost:1863"; //认证服务的url
option.RequireHttpsMetadata = false; //是否启用https
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseIdentityServer(); //修改的,登录获取token
app.UseAuthentication();//修改的,增加权限认证
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
//因为要使用登录的时候要使用数据中保存的用户进行验证,要实IResourceOwnerPasswordValidator接口:
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
public ResourceOwnerPasswordValidator()
{
}
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
//根据context.UserName和context.Password与数据库的数据做校验,判断是否合法
if (context.UserName == "wjk" && context.Password == "123")
{
context.Result = new GrantValidationResult(
subject: context.UserName,
authenticationMethod: "custom",
claims: GetUserClaims());
}
else
{
//验证失败
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid custom credential");
}
}
//可以根据需要设置相应的Claim
private Claim[] GetUserClaims()
{
return new Claim[]
{
new Claim("UserId", 1.ToString()),
new Claim(JwtClaimTypes.Name,"wjk"),
new Claim(JwtClaimTypes.GivenName, "jaycewu"),
new Claim(JwtClaimTypes.FamilyName, "yyy"),
new Claim(JwtClaimTypes.Email, "[email protected]"),
new Claim(JwtClaimTypes.Role,"admin")
};
}
}
public class ProfileService : IProfileService
{
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
try
{
//depending on the scope accessing the user data.
var claims = context.Subject.Claims.ToList();
//set issued claims to return
context.IssuedClaims = claims.ToList();
}
catch (Exception ex)
{
//log your error
}
}
public async Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
}
}
postman get 访问 :http://localhost:1863/connect/userinfo 记得带上token