前言 OAuth 2.0預設四種授權模式(GrantType) 授權碼模式(authorization_code) 簡化模式(implicit) "密碼模式( resource owner password credentials )" "客戶端模式(client_credentials)" 本章主 ...
前言
OAuth 2.0預設四種授權模式(GrantType)
- 授權碼模式(authorization_code)
- 簡化模式(implicit)
- 密碼模式(resource owner password credentials)
- 客戶端模式(client_credentials)
本章主要介紹密碼模式(resource owner password credentials),OAuth2.0資源所有者密碼授權功能允許客戶端將用戶名和密碼發送到令牌服務,並獲得該用戶的訪問令牌.
認證步驟:
- 用戶將用戶名密碼提供給客戶端
- 客戶端再將用戶名密碼發送給授權伺服器,請求令牌
- 授權伺服器確定判斷信息是否有誤,返回給客戶端令牌
創建授權伺服器
創建一個API項目工程,我這邊以埠5000的形式進行後面的講解.
Package
PM> Install-package IdentityServer4 -version 2.5.3
創建一個類Config(配置要保護的資源,和可以訪問的API的客戶端伺服器)
public class Config
{
/// <summary>
/// 定義要保護的資源
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> GetApiResources() {
return new List<ApiResource>
{
new ApiResource("api1","MyApi")
};
}
/// <summary>
/// 定義授權客戶端
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients() {
return new List<Client>
{
new Client(){
ClientId="client",
AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,
ClientSecrets=
{
new Secret("secret".Sha256())
},
AllowedScopes={ "api1",IdentityServerConstants.StandardScopes.OfflineAccess //如果要獲取refresh_tokens ,必須在scopes中加上OfflineAccess
},
AllowOfflineAccess=true// 主要刷新refresh_token,
}
};
}
}
此處AllowedGrantTypes需要設置為ResourceOwnerPassword(密碼憑證).
配置Startup
再走到ConfigureServices方法註入IdentityServer4服務
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();//註入自定義登錄驗證
}
IdentityServer4預設提供了兩種證書加密配置
AddDeveloperSigningCredential AddTemporarySigningCredential
添加記憶體ApiResourceAddInMemoryApiResources
添加記憶體Client AddInMemoryClients
添加自定義登錄驗證AddResourceOwnerValidator
自定義用戶驗證
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
if (context.UserName == "test" && context.Password == "test")
{
context.Result = new GrantValidationResult(
subject: context.UserName,
authenticationMethod: OidcConstants.AuthenticationMethods.Password);
}
else
{
//驗證失敗
context.Result = new GrantValidationResult(
TokenRequestErrors.InvalidGrant,
"invalid custom credential"
);
}
return Task.FromResult(0);
}
}
在Configure方法中添加IdentityServer4服務中間件
app.UseIdentityServer();
創建ApiResource
創建一個客戶端項目,這邊我將埠設置為5001
Package
PM> Install-package IdentityServer4 -version 2.5.3
配置Startup
在ConfigureServices添加認證伺服器地址
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";//授權伺服器地址
options.RequireHttpsMetadata = false;//不需要https
options.ApiName = "api1";
});
}
在Configure方法中添加認證服務中間件
app.UseAuthentication();
Run
在客戶端程式values控制器上面增加[Authorize]
直接訪問資源伺服器http://localhost:5001/api/values
code 401
啟動授權伺服器
http://localhost:5000/.well-known/openid-configuration
發現端點可通過/.well-known/openid-configuration
獲取token
這邊我用postman進行測試
code 200
access_token我們獲取到了,再拿著token通過postman請求資源程式,
code 200
成功了
refresh_token
獲取請求授權介面後會返回access_token expires
_in 等內容,expires_in是有效期(s),當然我們可以自定義有效期,access_token失效後用戶需要重新授權,client才能拿到新的access_token.但是有了refresh_token後,client檢測到token失效後可以直接通過refresh_token向授權伺服器申請新的token,當然refresh_token也是有有效期的。
AbsoluteRefreshTokenLifetime的預設有效期為2592000秒/30天。SlidingRefreshTokenLifetime的預設有效期為1296000秒/15天。
在認證伺服器中我再scopes加上了OfflineAccess
IdentityServerConstants.StandardScopes.OfflineAccess //如果要獲取refresh_tokens ,必須在scopes中加上OfflineAccess
獲取refresh_token
通過refresh_token再去獲取access_token
通過postman請求獲取資源
概要
示例地址https://github.com/fhcodegit/IdentityServer4.Samples