一步步搭建最简单oauth2.0认证和授权

时间:2022-09-17 22:22:00

oauth2.0 最早接触这个概念是在做微信订阅号开发。当时还被深深的绕进去,关于oauth2.0的解释网上有好多,而且都讲解的比较详细,下面给大家价格参考资料。

http://owin.org/

http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/ 

http://www.asp.net/aspnet/overview/owin-and-katana/an-overview-of-project-katana

http://www.asp.net/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline

http://www.asp.net/aspnet/overview/owin-and-katana/owin-startup-class-detection

http://msdn.microsoft.com/en-us/library/ff359101.aspx

接下来用最简短的代码实现author认证和授权。我们也可以先实现简单案例,在理解。

这里我以客户端模式为例。

1.ASP.NET MVC 4 Web API 项目或者MVC5

2. 添加引用

Owin.dll

Microsoft.Owin.dll

Microsoft.Owin.Host.SystemWeb.dll

Microsoft.Owin.Security.dll

Microsoft.Owin.Security.Oauth.dll

Microsoft.Owin.Security.Cookies.dll

MicrosoftAspNet.Identity.Owin.dll

3.修改 App_Start 文件夹下面 Startup.Auth.cs文件,把原来自动生成那些东西全部去掉。

public void ConfigureAuth(Owin.IAppBuilder app){

var OauthOptions = new Microsoft.Owin.Securtity.Oauth.OAuthAuthorizationServerOptions{

AllowInsecureHttp = true,

AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,

//获取 access_token 授权服务请求地址

TokenEndpointPath = new Microsoft.Owin.PathString("/token"),

//获取 authorization_code 授权服务请求地址

AuthorizeEndpointPath = new Microsoft.Owin.PathString("/authorize"),

//access_token 过期时间

AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(990),

//access_token 相关授权服务

Provider = new OpenAuthorizationServerProvider(),

//authorization_code 授权服务

RefreshTokenProvider = new OpenRefreshTokenProvider() //refresh_token 授权服务

};

app.UseOAuthBearerTokens(OAuthOptions);

}

修改Startup.cs 文件

[assembly: OwinStartup(typeof(WebApplication2.Startup))]

public partial class Startup

{

public void Configuration(IAppBuilder app)

{

ConfigureAuth(app);

var configuration = new HttpConfiguration();

WebApiConfig.Register(configuration);

app.UseWebApi(configuration);

}

}

上面这个文件的作用 相当于 Global.asax文件,在程序启动是及执行。

5. 新建 OpenAuthorizationServerProvider.cs 文件

public class OpenAuthorizationServerProvider :Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerProvider

{

/// <summary>

/// 验证 client 信息

/// </summary>

public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)

{

string clientId;

string clientSecret;

if (!context.TryGetBasicCredentials(out clientId, out clientSecret))

{

context.TryGetFormCredentials(out clientId, out clientSecret);

}

//对clientId 和 clientSecret 经行验证

context.Validated();

}

/// <summary>

/// 生成 access_token(client credentials 授权方式)

/// </summary>

public override async Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)

{

var identity = new ClaimsIdentity(new GenericIdentity(

context.ClientId, OAuthDefaults.AuthenticationType),

context.Scope.Select(x => new Claim("urn:oauth:scope", x)));

context.Validated(identity);

}

6.新建 OpenRefreshTokenProvider.cs 文件

public class OpenRefreshTokenProvider: AuthenticationTokenProvider

{

private static ConcurrentDictionary<string, string> _refreshTokens = new ConcurrentDictionary<string, string>();

/// <summary>

/// 生成 refresh_token

/// </summary>

public override void Create(AuthenticationTokenCreateContext context)

{

context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;

context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(60);

context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n"));

_refreshTokens[context.Token] = context.SerializeTicket();

}

/// <summary>

/// 由 refresh_token 解析成 access_token

/// </summary>

public override void Receive(AuthenticationTokenReceiveContext context)

{

string value;

if (_refreshTokens.TryRemove(context.Token, out value))

{

context.DeserializeTicket(value);

}

}

}

修改ValuesControl.cs

public class ValuesController : ApiController

{

[Authorize]

public IEnumerable<string> Get()

{

return new string[] { "value1", "value2" };

}

}

到这里整个author2.0 客户端模式 服务就待建好了。发布项目,这里发布地址我们定义:http://192.168.1.147:87。接下来我们搭建测试端。

7.新建 “控制台应用程序”。

8.新建 TokenResponse.cs 实体类。

public class TokenResponse

{

[JsonProperty("access_token")]

public string AccessToken { get; set; }

[JsonProperty("refresh_token")]

public string RefreshToken { get; set; }

[JsonProperty("token_type")]

public string TokenType { get; set; }

[JsonProperty("expires_in")]

public int expires_in { get; set; }

}

修改 Program.cs

static void Main(string[] args) {

Program p = new Program();

string result = p.Request_WebRequest("http://192.168.1.147:87/token", "ceshi", "123456", 500000);

}

public string Request_WebRequest(string uri, string username, string password, int timeout)

{

string result = string.Empty;

WebRequest request = WebRequest.Create(new Uri(uri));

if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))

{

request.Credentials = GetCredentialCache(new Uri(uri), username, password);

request.Headers.Add("Authorization", GetAuthorization(username, password));

}

if (timeout > 0)

request.Timeout = timeout;

request.Method = "POST";

request.ContentType = "application/x-www-form-urlencoded";

ASCIIEncoding asciiEncode = new ASCIIEncoding();

byte[] data = asciiEncode.GetBytes("grant_type=client_credentials");

request.ContentLength = data.Length;

Stream newStream = request.GetRequestStream();

newStream.Write(data, 0, data.Length);

newStream.Close();

WebResponse response = request.GetResponse();

Stream stream = response.GetResponseStream();

StreamReader sr = new StreamReader(stream);

result = sr.ReadToEnd();

TokenResponse tokenRes     =Newtonsoft.Json.JsonConvert.DeserializeObject<TokenResponse>(result);

 

request = WebRequest.Create(new Uri("http://192.168.1.147:87/api/values"));

string rha = "Bearer " + tokenRes.AccessToken;

request.Headers.Add("Authorization",rha);

request.Method = "Get";

response = request.GetResponse();

stream = response.GetResponseStream();

sr = new StreamReader(stream);

result = sr.ReadToEnd();

sr.Close();

stream.Close();

return result;

}

private static CredentialCache GetCredentialCache(Uri uri, string username, string password)

{

string authorization = string.Format("{0}:{1}", username, password);

CredentialCache credCache = new CredentialCache();

credCache.Add(uri, "Basic", new NetworkCredential(username, password));

return credCache;

}

private static string GetAuthorization(string username, string password)

{

string authorization = string.Format("{0}:{1}", username, password);

return "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(authorization));

}

运行测试,

得到["value1","value2"]

得到预期结果。

一步步搭建最简单oauth2.0认证和授权的更多相关文章

  1. OAuth2&period;0认证和授权以及单点登录

    https://www.cnblogs.com/shizhiyi/p/7754721.html OAuth2.0认证和授权机制讲解 2017-10-30 15:33 by shizhiyi, 2273 ...

  2. OAuth2&period;0认证和授权原理

    什么是OAuth授权?   一.什么是OAuth协议 OAuth(开放授权)是一个开放标准. 允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息. 而这种授权无需将用户提供用户名和密 ...

  3. &lbrack;转载&rsqb; OAuth2&period;0认证和授权原理

    转载自http://www.tuicool.com/articles/qqeuE3 什么是OAuth授权? 一.什么是OAuth协议 OAuth(开放授权)是一个开放标准,允许第三方网站在用户授权的前 ...

  4. OAuth2&period;0认证和授权机制讲解

    第一章.OAuth2.0 介绍 OAuth认证 OAuth认证是为了做到第三方应用在未获取到用户敏感信息(如:账号密码.用户PIN等)的情况下,能让用户授权予他来访问开放平台(主要访问平台中的资源服务 ...

  5. 使用Owin中间件搭建OAuth2&period;0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

  6. Spring Security OAuth2&period;0认证授权一:框架搭建和认证测试

    一.OAuth2.0介绍 OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不 需要将用户名和密码提供给第三方应用或分享他们数据的所有内容. 1.s ...

  7. Owin中间件搭建OAuth2&period;0认证授权服务体会

    继两篇转载的Owin搭建OAuth 2.0的文章,使用Owin中间件搭建OAuth2.0认证授权服务器和理解OAuth 2.0之后,我想把最近整理的资料做一下总结. 前两篇主要是介绍概念和一个基本的D ...

  8. Spring Security OAuth2&period;0认证授权二:搭建资源服务

    在上一篇文章[Spring Security OAuth2.0认证授权一:框架搭建和认证测试](https://www.cnblogs.com/kuangdaoyizhimei/p/14250374. ...

  9. Spring Cloud Zuul 网关使用与 OAuth2&period;0 认证授权服务

    API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...

随机推荐

  1. Android四种基本布局(LinearLayout &bsol; RelativeLayout &bsol; FrameLayout &bsol; TableLayout)

    ------------------------------------------LinearLayout---------------------------------------------- ...

  2. php &colon; mysql数据库操作类演示

    设计目标: 1,该类一实例化,就可以自动连接上mysql数据库: 2,该类可以单独去设定要使用的连接编码(set names XXX) 3,该类可以单独去设定要使用的数据库(use XXX): 4,可 ...

  3. Clojure的并行与并发

    这次来聊聊clojure的并行与并发,如果你还不知clojure为何物,请翻翻我的上一篇推文.“并行”是指clojure对并行计算的支持(parallel computing),“并发”是其并发特性( ...

  4. &period;NET导入openssl生成的公钥之BEGIN RSA PUBLIC KEY

    .NET导入openssl生成的公钥之BEGIN RSA PUBLIC KEY 我得到了一个公钥,形式如下 -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAMroxz3 ...

  5. &lbrack;原创&rsqb;obj-c编程15&lbrack;Cocoa实例02&rsqb;&colon;KVC和KVO的实际运用

    原文链接:obj-c编程15[Cocoa实例02]:KVC和KVO的实际运用 我们在第16和第17篇中分别介绍了obj-c的KVC与KVO特性,当时举的例子比较fun,太抽象,貌似和实际不沾边哦.那么 ...

  6. JGUI源码:Accordion鼠标中键滚动和手机端滑动实现&lpar;2&rpar;

    本文是抽屉组件在PC端滚动鼠标中键.手机端滑动时,滚动数据列表实现方法,没有使用iscroll等第三方插件,支持火狐,谷歌,IE8+等浏览器. 演示在:www.jgui.com Github地址:ht ...

  7. Python3练习题 001:4个数字求不重复的3位数

    #Python练习题 001:4个数字求不重复的3位数#方法一import itertoolsres = [][res.append(i[0]*100 + i[1]*10 + i[2]) for i ...

  8. JVM ——知识总结(面试)

    1)JAVA语言是一种强语言 2)JAVA不允许使用指针访问内存,不允许使用指针数组访问内存 3)有自动收集垃圾的作用 4)方法调用时,会创建栈帧在栈中,调用完是程序自动出栈释放,而不是gc释放 5) ...

  9. MYSQL启用日志,和查看日志

    mysql有以下几种日志:     错误日志:     -log-err     查询日志:     -log     慢查询日志:   -log-slow-queries     更新日志:     ...

  10. postgresql-死锁

    死锁问题:1.长事务,事务中包含了文书的上传下载,导致其他表的锁等待,最终导致死锁. 2.并发更新,如果更新慢的话,很可能导致,锁等待.需要加for update或者ad lock 3.数据库中查询p ...