ASP.NET OAuth授权 – 使用ClientId和Secret以及用户名和密码之间的区别
|
我正在尝试在ASP.NET WebAPI 2中实现一个简单的OAuthAuthorizationServerProvider.我的主要目的是学习如何为移动应用程序设置令牌.我希望用户使用用户名&密码,然后接收令牌(和刷新令牌,这样一旦令牌过期,他们就不必重新输入凭据).稍后,我希望有机会打开其他应用程序外部使用的API(比如使用Facebook api等……). 以下是我设置AuthorizationServer的方法: app.USEOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,TokenEndpointPath = new PathString("/token"),AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),Provider = new SimpleAuthorizationServerProvider(new SimpleAuthorizationServerProviderOptions()
{
ValidateUserCredentialsFunction = ValidateUser
}),RefreshTokenProvider = new SimpleRefreshTokenProvider()
});
这是我的SimpleAuthorizationServerProviderOptions实现: public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public delegate Task<bool> ClientCredentialsValidationFunction(string clientid,string secret);
public delegate Task<IEnumerable<Claim>> UserCredentialValidationFunction(string username,string password);
public SimpleAuthorizationServerProviderOptions Options { get; private set; }
public SimpleAuthorizationServerProvider(SimpleAuthorizationServerProviderOptions options)
{
if (options.ValidateUserCredentialsFunction == null)
{
throw new NullReferenceException("ValidateUserCredentialsFunction cannot be null");
}
Options = options;
}
public SimpleAuthorizationServerProvider(UserCredentialValidationFunction userCredentialValidationFunction)
{
Options = new SimpleAuthorizationServerProviderOptions()
{
ValidateUserCredentialsFunction = userCredentialValidationFunction
};
}
public SimpleAuthorizationServerProvider(UserCredentialValidationFunction userCredentialValidationFunction,ClientCredentialsValidationFunction clientCredentialsValidationFunction)
{
Options = new SimpleAuthorizationServerProviderOptions()
{
ValidateUserCredentialsFunction = userCredentialValidationFunction,ValidateClientCredentialsFunction = clientCredentialsValidationFunction
};
}
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
if (Options.ValidateClientCredentialsFunction != null)
{
string clientId,clientSecret;
if (!context.TryGetBasicCredentials(out clientId,out clientSecret))
{
context.TryGetFormCredentials(out clientId,out clientSecret);
}
var clientValidated = await Options.ValidateClientCredentialsFunction(clientId,clientSecret);
if (!clientValidated)
{
context.Rejected();
return;
}
}
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
if (Options.ValidateUserCredentialsFunction == null)
{
throw new NullReferenceException("ValidateUserCredentialsFunction cannot be null");
}
var claims = await Options.ValidateUserCredentialsFunction(context.UserName,context.Password);
if (claims == null)
{
context.Rejected();
return;
}
// create identity
var identity = new ClaimsIdentity(claims,context.Options.AuthenticationType);
// create metadata to pass to refresh token provider
var props = new AuthenticationProperties(new Dictionary<string,string>()
{
{ "as:client_id",context.UserName }
});
var ticket = new AuthenticationTicket(identity,props);
context.Validated(ticket);
}
public override async Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
{
var originalClient = context.Ticket.Properties.Dictionary["as:client_id"];
var currentClient = context.ClientId;
// enforce client binding of refresh token
if (originalClient != currentClient)
{
context.Rejected();
return;
}
// chance to change authentication ticket for refresh token requests
var newIdentity = new ClaimsIdentity(context.Ticket.Identity);
newIdentity.AddClaim(new Claim("newClaim","refreshToken"));
var newTicket = new AuthenticationTicket(newIdentity,context.Ticket.Properties);
context.Validated(newTicket);
}
}
我的SimpleRefreshTokenProvider实现: public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider
{
private static ConcurrentDictionary<string,AuthenticationTicket> _refreshTokens =
new ConcurrentDictionary<string,AuthenticationTicket>();
public void Create(AuthenticationTokenCreateContext context)
{
}
public async Task CreateAsync(AuthenticationTokenCreateContext context)
{
var guid = Guid.NewGuid().ToString();
var refreshTokenProperties = new AuthenticationProperties(context.Ticket.Properties.Dictionary)
{
IssuedUtc = context.Ticket.Properties.IssuedUtc,ExpiresUtc = DateTime.UtcNow.AddYears(1)
};
var refreshTokenTicket = new AuthenticationTicket(context.Ticket.Identity,refreshTokenProperties);
_refreshTokens.TryAdd(guid,refreshTokenTicket);
context.SetToken(guid);
}
public void Receive(AuthenticationTokenReceiveContext context)
{
}
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
AuthenticationTicket ticket;
if (_refreshTokens.TryRemove(context.Token,out ticket))
{
context.SetTicket(ticket);
}
}
}
我不完全理解的是使用ClientId和Secret vs用户名和密码.我粘贴的代码通过用户名和密码生成令牌,我可以使用该令牌(直到它过期),但是当我尝试获取刷新令牌时,我必须拥有ClientId. 此外,如果令牌过期,正确的方法是发送刷新令牌并获取新令牌?如果刷新令牌被盗怎么办?是不是用户名和&密码被盗? 解决方法
在OAuth2中,必须在协议定义的任何授权流中对用户和客户端进行身份验证.客户端身份验证(您可能猜到)仅强制使用您的API,只有已知客户端才能使用.序列化访问令牌一旦生成,就不会直接绑定到特定客户端.请注意,ClientSecret必须被视为机密信息,并且只能由能够以某种安全方式存储此信息的客户端使用(例如,外部服务客户端,而不是javascript客户端). 刷新令牌只是OAuth2的替代“授权类型”,并且正如您所说的那样,将替换用户的用户名和密码对.此令牌必须被视为机密数据(甚至比访问令牌更加机密),但优于存储用户名和密码.客户端密码: >如果受到损害,用户可以撤销; 我建议您阅读有关official draft中OAuth 2检查中定义的不同授权类型的更多信息.我还建议您this resource我发现在Web API中首次实现OAuth2时非常有用. 样品申请 以下是使用fiddler的两个请求示例,用于资源所有者密码凭据授予: 和刷新令牌授予: (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – System.Web.Security.FormsAuthentication.Encr
- asp.net-mvc-3 – ASP.NET MVC 3 MSChart错误:此数据系列只
- asp.net – 选择下拉列表项目findbytext没有区分大小写vb.n
- ASP.NET MVC 3自定义身份验证/授权
- asp.net-mvc – ASP.NET MVC强类型部分视图,无法加载类型错
- asp.net-mvc – 混合spark和webform视图引擎
- asp.net – Visual Studio无法在IIS中创建网站
- ASP.NET Web App和ASP.NET MVC 3 Empty Web App之间的区别?
- 认证 – 支持个人用户帐户和组织帐户在MVC5 / ASP.Net身份2
- asp.net – system.web.compilation.debug与system.codedom
- asp.net-mvc – 发生异常后不要刷新会话 – NHib
- asp.net-mvc-3 – 使用jQuery验证货币字段的客户
- 单个ASP.net网站与多个实例和web.configs
- asp.net – 如何尊重“从无Cookie域中提供静态内
- asp.net – 新的dotnet核心项目无法恢复
- asp.net-mvc – ASP.NET MVC:除了IE之外,我如何
- asp.net-mvc – 将焦点放在不使用JavaScript的Ed
- asp.net-mvc-3 – 如何指定默认LayoutPage在Razo
- asp.net-web-api – WebApi2属性路由404
- ASP.NET和C#有什么区别?
