标签:lan 发送 ref custom new extern count startup 四种
OAuth2四种模式
QQ,微信,等方式
请求
response_type:表示授权类型,必选项,此处的值固定为"code"
client_id:表示客户端的ID,必选项
redirect_uri:表示重定向URI,可选项
scope:表示申请的权限范围,可选项
state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
对于这种方式,试用在 访问一些和用户无关的Open Api,比如一些首页数据,这些数据和用户无关,但是又不想任何人都可以调用这个WebApi,那么就可以采用这种模式。
这个流程很像账号密码模式,但是它认证的是客户端身份,而不是用户
这种模式是很清晰的.就跟传统的验证一样.
grant_type:表示授权类型,此处的值固定为"password",必选项。
username:表示用户名,必选项。
password:表示用户的密码,必选项。
scope:表示权限范围,可选项。
public class Startup
{
public void Configuration(IAppBuilder app)
{
//授权配置
var OAuthOptions = new OAuthAuthorizationServerOptions
{
//获取Token的路径
TokenEndpointPath = new PathString("/Token"),
//自定义的 校验,授权器
Provider = new ApplicationOAuthProvider(),
//我们不想让客户端直接输入凭据,需要一个服务器进行发放授权,这个就像点开QQ第三方登入弹出的登入页面.AuthorizeEndpointPath就是这种页面的地址
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
//Token 过期时间,默认20分钟
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
//在生产模式下设 AllowInsecureHttp = false
AllowInsecureHttp = true
};
app.UseOAuthBearerTokens(OAuthOptions);
}
}
通过请求TokenEndpointPath获得Access_Token
Owin.OAuth提供的授权方式有
UseOAuthBearerTokens 内部包含了
通过基础OAuthAuthorizationServerProvider来定义自己的授权,通过重写上述相应的方法来选择不同的授权模式.这些方法触发条件就是grant_type
,不同的值会触发不同的方法.
但在这之前必须经过ValidateClientAuthentication
.因为整个流程就是认证->授权
,认证是判断这个用户是否是本系统的,授权是给予用户相应的标记,该标记不仅标示用户身份也表示用户的权限.
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
public ApplicationOAuthProvider()
{
}
///
/// 客户端验证,这是必须通过的方法,确保客户端是正确的,这里通过后才能开始授权
///
///
///
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
//context.TryGetFormCredentials() 从表单中获取clientId,clientSecret
//context.TryGetBasicCredentials 从Authenticate Base解密 获取clientId,lientSecret
//在数据库中查看clientId的有效性
//在这里还没有些clientId,所以下面这句意思是,如果不是使用password认知方式,则直接验证通过,其clientId设置为12
if (context.Parameters["username"] == null && context.Parameters["password"] == null)
{
context.Validated("123");
}
return base.ValidateClientAuthentication(context);
}
///
/// 账号密码授权,grant_type:password
///
///
///
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
//生成token
var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
context.Validated(ticket);//授权
return base.GrantResourceOwnerCredentials(context);
}
///
/// 对客户端进行授权,grant_type:client_credentials
///
///
///
public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
{
var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
context.Request.Body.Seek(0, SeekOrigin.Begin);
//从报文体重获取数据
string FormStr = new StreamReader(context.Request.Body).ReadToEnd();
var FormKeyValues = HttpUtility.ParseQueryString(FormStr);
//登入
var loginresult = AsyncHelper.RunSync<LoginOutput>(()=>studentLoginApp.Login(new LoginInput()
{
StuNum = FormKeyValues["StuNum"],
Psw = FormKeyValues["Psw"]
}));
//添加Cookie到声明
oAuthIdentity.AddClaim(new Claim(loginresult.Cookie.Name, loginresult.Cookie.Value));
//添加学号
oAuthIdentity.AddClaim(new Claim(ClaimTypes.UserData, loginresult.StuNum));
//生成token
var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
context.Validated(ticket);
return base.GrantClientCredentials(context);
}
}
这里重写了3个方法
- ValidateClientAuthentication
- GrantResourceOwnerCredentials
- GrantClientCredentials
当请求Access_Token时候必定经过ValidateClientAuthentication,这个通常客户端会带上clientId,lientSecret,在此验证两个数据的正确性,得知该客户端是否有权向本网站申请授权
当通过ValidateClientAuthentication后,则会根据请求中的grant_type来调用GrantResourceOwnerCredentials(password)或GrantClientCredentials(client_credentials)
GrantClientCredentials一般用于普通资源的授权,就是人人都能使用的资源.
GrantResourceOwnerCredentials 则是对用户有要求,需要登入才能使用资源,在这个方法中可以给用户Claim添加数据,比如Role,并再资源上打上Authentication(Role=”“)来限制
这个是普通资源请求,按理要加上clientId,clientSecret可以直接加到Body中,也可以加到Headers的Authorization
注意这里的Body一定要是x-www-form-urlencoded,否则后端识别不出来,在ajax的时候可能会出问题
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)));
如果数据都正确则能获得Access_Token
在这之后的请求需要要把Access_Token添加到Authorization中
标签:lan 发送 ref custom new extern count startup 四种
原文地址:http://www.cnblogs.com/Recoding/p/7182314.html