ms随vs2013推出了mvc5,mvc5自带的模板项目中引用了新的身份认证框架 ms identity。其中owin部分实现了google,facebook,twitter等国外常见的第三方用户。可惜国内没人用这些。

只能照猫画虎实现以下qq和sina的了

首先看ms自带的google和facebook的代码

每个类库里,有6个类一个接口,其中扩展类放在Owin命名空间下,是为了在startup中方便调用

看看startup中被注释掉的代码就知道了,都是UsexxxAuthentication。同理,希望可以有

app.UseQQAuthentication和app.UseSinaAuthentication

通过查看扩展方法,可以发现,最终调用了app.Use

对应的FacebookAuthenticationMiddleware和GoogleAuthenticationMiddleware才是owin相关的关键部分

XXXMiddleware是一个实现了OwinMiddleware的类(Middleware译为中间件),继承他,然后Use到app里,就可以在Invoke时去处理请求

不过我们不需要继承OwinMiddleware这么底层的类,因为有与身份认证相关的中间件基类了

public abstract class AuthenticationMiddleware<TOptions> : OwinMiddleware where TOptions : AuthenticationOptions

看此类的签名就知道,我们还需要一个Options类,应该去继承AuthenticationOptions类


看看微软给的。在options类里,一般都会有一些属性,去让使用者设定appid和appkey等信息,对oauth验证来说,基本就这两个是最重要的。

稍微需要注意一下的是

base(“Google”)中的google是写死传进去的,这个对应的是

这里的文字

而Caption对应的是

这里的文字(鼠标悬停出现的)

如果希望按钮的文字也由使用者提供,可以实现带参的构造

来看看最核心的中间件吧。

已google的为例,发现他并没有实现Invoke方法,那就应该是在基类里已经实现了。

反而是实现了一个CreateHandler方法

new了一个GoogleAuthenticationHandler返回

再看看facebook的

也一样。在对象浏览器里没发现这个Handler类啊。好在有各种反编译。

这个是个internal的类(最恨internal和sealed)

看看中间件类里,比较简单

1、构造函数就是给options赋一些默认值

2、创建Handler

3、私有方法,在构造中调用

没了

那核心明显从中间件转到了Handler

再看Handler之前,先看看其他的那几个类

XXXReturnEndpointContext实现ReturnEndpointContext,除了构造没别的

太简单了,咱也整个QQReturnEndpointContext和SinaReturnEndpointContext放着

再看IGoogleAuthenticationProvider和IFacebookAuthenticationProvider,都一样的

Task Authenticated(FacebookAuthenticatedContext context);
Task ReturnEndpoint(FacebookReturnEndpointContext context);

除了参数的类型不一样外,其他的都一样的。我们也写一个放着。

再看接口的实现,也一样的,代码不贴了。写两个放着。

到目前为止,我们有以下几个类

1、扩展方法来

2、Options类

3、中间件类

4、Handler类

5、ReturnEndpointContext类

6、Provider接口

7、Provider实现

还剩下一个XXXAuthenticatedContext类

看google和facebook的实现可以发现,只有属性,没有方法,属性就是记录以下用户id,用户名字acesskey等信息

我们可以先把类建好,具体属性需要什么根据对应的api再加。

OK,我们回来看核心的Handler类。

可以发现,他们都实现了基类的3个方法

1、

protected override Task ApplyResponseChallengeAsync()

2、

public override async Task<bool> InvokeAsync()

3、

protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()

先说第一个,他的作用就是方法第三方api,看看是否授权了

对应的qq地址是:

https://graph.qq.com/oauth2.0/authorize?client_id={0}&response_type=code&redirect_uri={1}

对应的sina地址是:

https://api.weibo.com/oauth2/authorize?client_id={0}&redirect_uri={1}&response_type=code&state={2}
在方法的最后,通过
this.Response.StatusCode = 302;
this.Response.Headers.Set("Location", url);

来设置浏览器跳转

在连接中,我们需要有一个state参数,这个参数由app生成,传给oauth,oauth在传回来,对比验证,state生成后,会自动保存到cookie里,这是基类帮我们做好的。

AuthenticationProperties properties = responseChallenge.Properties;
this.GenerateCorrelationId(properties);
var protector=this.Options.StateDataFormat.Protect(properties);

只需要3行代码,就可以生成一个state验证串,把这个字符串附加在连接后面传给oauth即可

oauth的回调地址,是定义在Options里的CallbackPath

在对应的Options类里可以看到地址为/signin-google和signin-facebook,我们自己的qq和sina自然可以定义成signin-qq和signin-sina

找遍项目,也没有发现signin-google这个controller或者页面什么的,那为什么这个地址可以访问呢,访问他又会干什么呢

来看第二个方法InvokeAsync()

已google为例

public override async Task<bool> InvokeAsync()
{bool flag;if (this.Options..HasValue && this.Options. == this.Request.Path)flag = await this.();elseflag = false;return flag;
}

在这里判断了,如果当前访问的路径是CallbackPath的路径,则去执行一些东西,下面的InvokeReturnPathAsync是一个protected方法

真正的逻辑在这个方法里

public async Task<bool> InvokeReturnPathAsync()
{AuthenticationTicket model = await this.AuthenticateAsync();bool flag;if (model == null){LoggerExtensions.WriteWarning(this._logger, "Invalid return state, unable to redirect.", new string[0]);this.Response.StatusCode = 500;flag = true;}else{GoogleReturnEndpointContext context = new GoogleReturnEndpointContext(this.Context, model);context.SignInAsAuthenticationType = this.Options.SignInAsAuthenticationType;context.RedirectUri = model.Properties.RedirectUri;model.Properties.RedirectUri = (string) null;await this.Options.Provider.ReturnEndpoint(context);if (context.SignInAsAuthenticationType != null && context.Identity != null){ClaimsIdentity claimsIdentity = context.Identity;if (!string.Equals(claimsIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal))claimsIdentity = new ClaimsIdentity(claimsIdentity.Claims, context.SignInAsAuthenticationType, claimsIdentity.NameClaimType, claimsIdentity.RoleClaimType);this.Context.Authentication.SignIn(context.Properties, new ClaimsIdentity[1]{claimsIdentity});}if (!context.IsRequestCompleted && context.RedirectUri != null){if (context.Identity == null)context.RedirectUri = WebUtilities.AddQueryString(context.RedirectUri, "error", "access_denied");this.Response.Redirect(context.RedirectUri);context.RequestCompleted();}flag = context.IsRequestCompleted;}return flag;
}
(google和facebook的,除了类名不一样,其他的都一样,copy一下就可以了。)
所以,当回调到signin-google这个地址的时候,是可以正常访问的。
 
最后来看AuthenticateCoreAsync
首先是检查回调地址的参数,如果没有state,就返回null了。
然后是
this.ValidateCorrelationId(properties, this._logger)

通过这个方法,来与cookie里保存的state对比,如果不对,也返回null了

剩下的就是回调正确,改进行下一步了。
 
最终的目的是要返回一个AuthenticationTicket
public AuthenticationTicket(ClaimsIdentity identity, AuthenticationProperties properties)

需要2个参数,其中properties我们已经有了(在前面就可以构造出来,具体可看源码)

这里主要是需要构造一个ClaimsIdentity
ClaimsIdentity identity = new ClaimsIdentity(this.Options.AuthenticationType);

理论上new一个就ok,并且,如果仅仅是这么写,他也能过去的,会进入下一步,但是到下一步的时候,有时候会包nullreference异常。

这里应该传入当前用户id和名字

identity.AddClaim(new Claim(http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier, 
, "http://www.w3.org/2001/XMLSchema#string", this.Options.AuthenticationType));
identity.AddClaim(new Claim(http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name,
 , "http://www.w3.org/2001/XMLSchema#string", this.Options.AuthenticationType));

至少需要id,第一次用第三方登录进来时,他会让你在本地注册

此时AspNetUserLogins表中会加入一条数据

联合主键,UserId对应AspNetUsers表中的主键

LoginProvider是你所使用的第三方登录的标识就是Options调用base(“xxxx”)这里传进去的那个值

而最后一个ProviderKey,则是你这个第三方登录返回的用户id,比如你用sina的登陆,这里记录的应该是你sina的那个id

qq的,就是qq记录你的那个id(qq的叫open id)

具体这几个表是如何存储,是和MS Identity有关的。

这个id和名字这么获得?

当然是调用oauth的api了。

目前,我们只是调用了授权服务,回调的参数里有authorization code,我们需要拿这个authorization code 去请求access token,再拿access token 去请求当前的人的昵称和id等其他信息

简单实现了一下

https://github.com/czcz1024/OwinQQ

包括qq和sina的,因为不想引入其他的类库,所以id,名字还包括access token等都是拿正则截取的,如果你觉得不爽,可以自己做json转换

转载于:https://www.cnblogs.com/czcz1024/p/3498118.html

照猫画虎owin oauth for qq and sina相关推荐

  1. python发送qq邮件_python使用SMTP发送qq或sina邮件

    python使用qq邮箱(个人邮箱)发送邮件需开启qq邮箱的SMTP服务 在设置中开启pop3/SMTP服务,返回的密码就是之后代码中登录使用账户密码(在完整代码中标识了出来) 之后出现如下错误 复制 ...

  2. owin Oauth

    原文:http://www.cnblogs.com/richieyang/p/4918819.html 一.什么是OAuth OAuth是一个关于授权(Authorization)的开放网络标准,目前 ...

  3. 在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token

    OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手.因此,Microsoft.Owin.Security.OAuth应运而生(它的实现代码在Katana项目中),帮 ...

  4. ASP.NET Web API与Owin OAuth:使用Access Toke调用受保护的API(二)

    在前一篇博文中,我们使用OAuth的Client Credential Grant授权方式,在服务端通过CNBlogsAuthorizationServerProvider(Authorization ...

  5. ASP.NET Web API与Owin OAuth:使用Access Toke调用受保护的API

    在前一篇博文中,我们使用OAuth的Client Credential Grant授权方式,在服务端通过CNBlogsAuthorizationServerProvider(Authorization ...

  6. 这里是通过QQ邮箱 sina新浪邮箱 163邮箱的简单发送Email

    1.首先去官网下载发送Email的相应的jar文件如 smtp.jar mailapi.jar等 2.去QQ  sina 163中的设置里开启POP3/IMAP/SMTP/Exchange/CardD ...

  7. ASP.NET WebApi OWIN 实现 OAuth 2.0

    OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...

  8. Windows Phone 7, Hammock, OAuth and Sina Weibo’s API

    Windows Phone 7, Hammock, OAuth and Sina Weibo's API Link:http://www.binzywu.com/2011/02/windows-pho ...

  9. Android分享功能,微博、QQ、QQ空间等社交平台分享之入门与进阶

    前言 如何能迅速做一个分享功能,那主要就是根据第一个步骤来做就好了,因为友盟的sdk包已经集成很多的内容了,只要你有相应的app和平台账号就可以能马上分享.进阶的内容就是从第三部分开始,这些内容不难, ...

  10. python的flask实现第三方登录怎么写_Python语言的Flask框架应用程序实现使用QQ账号登录的方法...

    本文主要向大家介绍了Python语言的Flask框架应用程序实现使用QQ账号登录的方法,希望对大家学习Python语言有所帮助. Flask-OAuthlib是OAuthlib的Flask扩展实现, ...

最新文章

  1. linux bin文件制作
  2. Spring学习之旅(四):面向切面编程(AOP)
  3. html代码重排,是否有可能在html中格式化/重排html?
  4. Vue:中向对象中添加数据
  5. JAVA 初级程序员常见问题分析
  6. java 开根号函数_java如何开根号?
  7. 三极管和MOS管的区别
  8. 003内部仓储物流的“降维打击”
  9. 南京商品住宅全装修新政:毛坯、装修价格分别备案
  10. 1一9数字行书写法_1一9数字行书写法
  11. outlook签名文件编辑_如何在Microsoft Outlook中创建,编辑和应用签名
  12. 修改elementUI中分页器的背景色
  13. 中华活页文选杂志中华活页文选杂志社中华活页文选编辑部2022年第8期目录
  14. 2017 终点亦是起点
  15. 个人博客系统【项目篇】
  16. 网易邮箱中非常实用的工具,手机、IP等归属地
  17. 【离散数学】-【web-软件测试-java-等】-面试汇总
  18. 用excle插入自定义两列(行)数据作为X、Y轴生成图表
  19. 必看!gitee上开源的商城源码
  20. 怎么让图片动起来?教你让图片动起来的方法

热门文章

  1. [数据结构]P1.3 栈 Stack
  2. Tortoise svn 基础知识
  3. Stanford NLP 第四课 神经网络复习
  4. 【Codeforces Round #422 (Div. 2) C】Hacker, pack your bags!(hash写法)
  5. 可以掉落和滑动的星星
  6. api 读内存整数_10万+QPS 真的只是因为单线程和基于内存?
  7. 对应版本_DNF:韩服新增天域之母等13件特殊史诗,老版本装备全部直升100级
  8. html 表格中单选框触发事件_HTML基础知识(网站同步更新)
  9. SparkStreaming自定义Receiver
  10. HBase的两种协处理器