linux软件运行授权,使用控制台程序搭建OAuth授权服务器

详细讲解使用控制台程序搭建OAuth授权服务器,先上一张OAuth的认证图

b5fe8971a344009aa40168e58ec1c633.png

很多情况下授权服务器和资源服务器时同一台机器,就有了下面这张图

7d069f044c998d98726d78c2bd126c07.png

接着可以使用上一篇文章中的控制台程序,做一些改动

首先需要引入Microsoft.AspNet.Identity.Owin包

PM> Install-Package Microsoft.AspNet.Identity.Owin -Pre

添加一个授权提供类ApplicationOAuthServerProvider继承自Microsoft.Owin.Security.OAuth中的OAuthAuthorizationServerProvider ,这个类实现了IOAuthAuthorizationServerProvider接口

86c496eef837b2acb4915438dc4f1c5e.gif

usingMicrosoft.Owin.Security.OAuth;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Security.Claims;usingSystem.Text;usingSystem.Threading.Tasks;namespaceConsoleWebApi.OAuthServerProvider

{public classApplicationOAuthServerProvider: OAuthAuthorizationServerProvider

{public override asyncTask ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)

{//This call is required...//but we're not using client authentication, so validate and move on...

awaitTask.FromResult(context.Validated());

}public override asyncTask GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

{//DEMO ONLY: Pretend we are doing some sort of REAL checking here:

if (context.Password != "password")

{

context.SetError("invalid_grant", "The user name or password is incorrect.");

context.Rejected();return;

}//Create or retrieve a ClaimsIdentity to represent the//Authenticated user:

ClaimsIdentity identity =

newClaimsIdentity(context.Options.AuthenticationType);

identity.AddClaim(new Claim("user_name", context.UserName));//Add a Role Claim:

identity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));//Identity info will ultimately be encoded into an Access Token//as a result of this call:

context.Validated(identity);

}

}

}

View Code

这里重写了两个方法:

ValidateClientAuthentication()验证客户信息。

GrantResourceOwnerCredentials()创建ClaimsIdentity并通过OWIN middleware将ClaimsIdentity编码生成Access Token。

Suffice it to say that theClaimsIdentity information is encrypted with a private key (generally, but not always the Machine Key of the machine on which the server is running). Once so encrypted, the access token is then added to the body of the outgoing HTTP response.

大意就时通过机器的Machine Key将ClaimsIdentity编码,如果资源服务器和授权服务器不是同一台机器的话,需要在配置文件中配置相同的Machine Key,这样通过OWIN 中间件就能解码出ClaimsIdentity。

下一步修改Startup ,添加ConfigureAuth()

86c496eef837b2acb4915438dc4f1c5e.gif

Startup class. Check to make sure you have added the following usings and code to Startup:

Add a ConfigureAuth() Method to the OWIN Startup Class:usingSystem;//Add the following usings:

usingOwin;usingSystem.Web.Http;usingMinimalOwinWebApiSelfHost.Models;usingMinimalOwinWebApiSelfHost.OAuthServerProvider;usingMicrosoft.Owin.Security.OAuth;usingMicrosoft.Owin;namespaceMinimalOwinWebApiSelfHost

{public classStartup

{//This method is required by Katana:

public voidConfiguration(IAppBuilder app)

{

ConfigureAuth(app);var webApiConfiguration =ConfigureWebApi();

app.UseWebApi(webApiConfiguration);

}private voidConfigureAuth(IAppBuilder app)

{var OAuthOptions = newOAuthAuthorizationServerOptions

{

TokenEndpointPath= new PathString("/Token"),

Provider= newApplicationOAuthServerProvider(),

AccessTokenExpireTimeSpan= TimeSpan.FromDays(14),//Only do this for demo!!

AllowInsecureHttp = true};

app.UseOAuthAuthorizationServer(OAuthOptions);

app.UseOAuthBearerAuthentication(newOAuthBearerAuthenticationOptions());

}privateHttpConfiguration ConfigureWebApi()

{var config = newHttpConfiguration();

config.Routes.MapHttpRoute("DefaultApi","api/{controller}/{id}",new { id =RouteParameter.Optional });returnconfig;

}

}

}

View Code

接下来新建一个客户端控制台程序

添加几个类

ApiClientProvider

86c496eef837b2acb4915438dc4f1c5e.gif

af9684e26bfcb368e633a8bc468b1056.gif

usingNewtonsoft.Json;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net.Http;usingSystem.Text;usingSystem.Threading.Tasks;namespaceMinimalOwinWebApiClient

{public classApiClientProvider

{string_hostUri;public string AccessToken { get; private set; }public ApiClientProvider(stringhostUri)

{

_hostUri=hostUri;

}public async Task>GetTokenDictionary(string userName, stringpassword)

{

HttpResponseMessage response;var pairs = new List>{new KeyValuePair( "grant_type", "password"),new KeyValuePair( "username", userName ),new KeyValuePair ( "password", password )

};var content = newFormUrlEncodedContent(pairs);using (var client = newHttpClient())

{var tokenEndpoint = new Uri(new Uri(_hostUri), "Token");

response= awaitclient.PostAsync(tokenEndpoint, content);

}var responseContent = awaitresponse.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode)

{throw new Exception(string.Format("Error: {0}", responseContent));

}returnGetTokenDictionary(responseContent);

}private DictionaryGetTokenDictionary(stringresponseContent)

{

Dictionary tokenDictionary =JsonConvert.DeserializeObject>(

responseContent);returntokenDictionary;

}

}

}

View Code

Company

86c496eef837b2acb4915438dc4f1c5e.gif

public classCompany

{public int Id { get; set; }public string Name { get; set; }

}

View Code

CompanyClient

86c496eef837b2acb4915438dc4f1c5e.gif

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Http;usingSystem.Net.Http.Headers;usingSystem.Text;usingSystem.Threading.Tasks;namespaceMinimalOwinWebApiClient

{public classCompanyClient

{string_accessToken;

Uri _baseRequestUri;public CompanyClient(Uri baseUri, stringaccessToken)

{

_accessToken=accessToken;

_baseRequestUri= new Uri(baseUri, "api/companies/");

}//Handy helper method to set the access token for each request:

voidSetClientAuthentication(HttpClient client)

{

client.DefaultRequestHeaders.Authorization= new AuthenticationHeaderValue("Bearer", _accessToken);

}public async Task>GetCompaniesAsync()

{

HttpResponseMessage response;using (var client = newHttpClient())

{

SetClientAuthentication(client);

response= awaitclient.GetAsync(_baseRequestUri);

}return await response.Content.ReadAsAsync>();

}public async Task GetCompanyAsync(intid)

{

HttpResponseMessage response;using (var client = newHttpClient())

{

SetClientAuthentication(client);//Combine base address URI and ID to new URI//that looks likehttp://hosturl/api/companies/id

response = awaitclient.GetAsync(newUri(_baseRequestUri, id.ToString()));

}var result = await response.Content.ReadAsAsync();returnresult;

}public async TaskAddCompanyAsync(Company company)

{

HttpResponseMessage response;using (var client = newHttpClient())

{

SetClientAuthentication(client);

response= awaitclient.PostAsJsonAsync(

_baseRequestUri, company);

}returnresponse.StatusCode;

}public async TaskUpdateCompanyAsync(Company company)

{

HttpResponseMessage response;using (var client = newHttpClient())

{

SetClientAuthentication(client);

response= awaitclient.PutAsJsonAsync(

_baseRequestUri, company);

}returnresponse.StatusCode;

}public async Task DeleteCompanyAsync(intid)

{

HttpResponseMessage response;using (var client = newHttpClient())

{

SetClientAuthentication(client);//Combine base address URI and ID to new URI//that looks likehttp://hosturl/api/companies/id

response = awaitclient.DeleteAsync(newUri(_baseRequestUri, id.ToString()));

}returnresponse.StatusCode;

}

}

}

View Code

修改Main

86c496eef837b2acb4915438dc4f1c5e.gif

af9684e26bfcb368e633a8bc468b1056.gif

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceMinimalOwinWebApiClient

{classProgram

{static void Main(string[] args)

{//Wait for the async stuff to run...

Run().Wait();//Then Write Done...

Console.WriteLine("");

Console.WriteLine("Done! Press the Enter key to Exit...");

Console.ReadLine();return;

}static asyncTask Run()

{//Create an http client provider:

string hostUriString = "http://localhost:8080";var provider = newApiClientProvider(hostUriString);string_accessToken;

Dictionary_tokenDictionary;try{//Pass in the credentials and retrieve a token dictionary:

_tokenDictionary = awaitprovider.GetTokenDictionary("john@example.com", "password");

_accessToken= _tokenDictionary["access_token"];//Write the contents of the dictionary:

foreach (var kvp in_tokenDictionary)

{

Console.WriteLine("{0}: {1}", kvp.Key, kvp.Value);

Console.WriteLine("");

}//Create a company client instance:

var baseUri = newUri(hostUriString);var companyClient = newCompanyClient(baseUri, _accessToken);//Read initial companies:

Console.WriteLine("Read all the companies...");var companies = awaitcompanyClient.GetCompaniesAsync();

WriteCompaniesList(companies);int nextId = (from c in companies select c.Id).Max() + 1;

Console.WriteLine("Add a new company...");var result = awaitcompanyClient.AddCompanyAsync(new Company { Name = string.Format("New Company #{0}", nextId) });

WriteStatusCodeResult(result);

Console.WriteLine("Updated List after Add:");

companies= awaitcompanyClient.GetCompaniesAsync();

WriteCompaniesList(companies);

Console.WriteLine("Update a company...");var updateMe = awaitcompanyClient.GetCompanyAsync(nextId);

updateMe.Name= string.Format("Updated company #{0}", updateMe.Id);

result= awaitcompanyClient.UpdateCompanyAsync(updateMe);

WriteStatusCodeResult(result);

Console.WriteLine("Updated List after Update:");

companies= awaitcompanyClient.GetCompaniesAsync();

WriteCompaniesList(companies);

Console.WriteLine("Delete a company...");

result= await companyClient.DeleteCompanyAsync(nextId - 1);

WriteStatusCodeResult(result);

Console.WriteLine("Updated List after Delete:");

companies= awaitcompanyClient.GetCompaniesAsync();

WriteCompaniesList(companies);

}catch(AggregateException ex)

{//If it's an aggregate exception, an async error occurred:

Console.WriteLine(ex.InnerExceptions[0].Message);

Console.WriteLine("Press the Enter key to Exit...");

Console.ReadLine();return;

}catch(Exception ex)

{//Something else happened:

Console.WriteLine(ex.Message);

Console.WriteLine("Press the Enter key to Exit...");

Console.ReadLine();return;

}

}static void WriteCompaniesList(IEnumerablecompanies)

{foreach (var company incompanies)

{

Console.WriteLine("Id: {0} Name: {1}", company.Id, company.Name);

}

Console.WriteLine("");

}static voidWriteStatusCodeResult(System.Net.HttpStatusCode statusCode)

{if (statusCode ==System.Net.HttpStatusCode.OK)

{

Console.WriteLine("Opreation Succeeded - status code {0}", statusCode);

}else{

Console.WriteLine("Opreation Failed - status code {0}", statusCode);

}

Console.WriteLine("");

}

}

}

View Code

给CompaniesController加上[Authorize]后就有了授权认证了。

0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值