public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider { public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (!context.TryGetBasicCredentials(out clientId, out clientSecret)) { context.TryGetFormCredentials(out clientId, out clientSecret); }
if (clientId != "xishuai") { context.SetError("invalid_client", "client is not valid"); return; } context.Validated(); }
public override async Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context) { if (context.AuthorizeRequest.IsImplicitGrantType) { var identity = new ClaimsIdentity("Bearer"); context.OwinContext.Authentication.SignIn(identity); context.RequestCompleted(); } else if (context.AuthorizeRequest.IsAuthorizationCodeGrantType) { var redirectUri = context.Request.Query["redirect_uri"]; var clientId = context.Request.Query["client_id"]; var identity = new ClaimsIdentity(new GenericIdentity( clientId, OAuthDefaults.AuthenticationType));
var authorizeCodeContext = new AuthenticationTokenCreateContext( context.OwinContext, context.Options.AuthorizationCodeFormat, new AuthenticationTicket( identity, new AuthenticationProperties(new Dictionary<string, string> { {"client_id", clientId}, {"redirect_uri", redirectUri} }) { IssuedUtc = DateTimeOffset.UtcNow, ExpiresUtc = DateTimeOffset.UtcNow.Add(context.Options.AuthorizationCodeExpireTimeSpan) }));
public class OpenAuthorizationCodeProvider : AuthenticationTokenProvider { private readonly ConcurrentDictionary<string, string> _authenticationCodes = new ConcurrentDictionary<string, string>(StringComparer.Ordinal);
public class OpenRefreshTokenProvider : AuthenticationTokenProvider { private static ConcurrentDictionary<string, string> _refreshTokens = new ConcurrentDictionary<string, string>();
public class OAuthClientTest { private const string HOST_ADDRESS = "http://localhost:8001"; private IDisposable _webApp; private static HttpClient _httpClient;
public OAuthClientTest() { _webApp = WebApp.Start<Startup>(HOST_ADDRESS); Console.WriteLine("Web API started!"); _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri(HOST_ADDRESS); Console.WriteLine("HttpClient started!"); }
private static async Task<TokenResponse> GetToken(string grantType, string refreshToken = null, string userName = null, string password = null, string authorizationCode = null) { var clientId = "xishuai"; var clientSecret = "123"; var parameters = new Dictionary<string, string>(); parameters.Add("grant_type", grantType);
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password)) { parameters.Add("username", userName); parameters.Add("password", password); } if (!string.IsNullOrEmpty(authorizationCode)) { parameters.Add("code", authorizationCode); parameters.Add("redirect_uri", "http://localhost:8001/api/authorization_code"); } if (!string.IsNullOrEmpty(refreshToken)) { parameters.Add("refresh_token", refreshToken); }
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)));
var response = await _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)); var responseValue = await response.Content.ReadAsStringAsync(); if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine(response.StatusCode); Console.WriteLine((await response.Content.ReadAsAsync<HttpError>()).ExceptionMessage); return null; } return await response.Content.ReadAsAsync<TokenResponse>(); }
private static async Task<string> GetAuthorizationCode() { var clientId = "xishuai";
var response = await _httpClient.GetAsync($"/authorize?grant_type=authorization_code&response_type=code&client_id={clientId}&redirect_uri={HttpUtility.UrlEncode("http://localhost:8001/api/authorization_code")}"); var authorizationCode = await response.Content.ReadAsStringAsync(); if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine(response.StatusCode); Console.WriteLine((await response.Content.ReadAsAsync<HttpError>()).ExceptionMessage); return null; } return authorizationCode; }
[Fact] public async Task OAuth_AuthorizationCode_Test() { var authorizationCode = GetAuthorizationCode().Result; var tokenResponse = GetToken("authorization_code", null, null, null, authorizationCode).Result; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
var response = await _httpClient.GetAsync($"/api/values"); if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine(response.StatusCode); Console.WriteLine((await response.Content.ReadAsAsync<HttpError>()).ExceptionMessage); } Console.WriteLine(await response.Content.ReadAsStringAsync()); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Thread.Sleep(10000);
var tokenResponseTwo = GetToken("refresh_token", tokenResponse.RefreshToken).Result; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponseTwo.AccessToken); var responseTwo = await _httpClient.GetAsync($"/api/values"); Assert.Equal(HttpStatusCode.OK, responseTwo.StatusCode); } }
var identity = new ClaimsIdentity("Bearer"); context.OwinContext.Authentication.SignIn(identity); context.RequestCompleted();
这段代码执行会直接回调 redirect_uri,并附上 access_token,接受示例代码:
1 2 3 4 5 6 7 8 9 10
[HttpGet] [Route("api/access_token")] public HttpResponseMessage GetToken() { var url = Request.RequestUri; return new HttpResponseMessage() { Content = new StringContent("", Encoding.UTF8, "text/plain") }; }
单元测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
[Fact] public async Task OAuth_Implicit_Test() { var clientId = "xishuai";
var tokenResponse = await _httpClient.GetAsync($"/authorize?response_type=token&client_id={clientId}&redirect_uri={HttpUtility.UrlEncode("http://localhost:8001/api/access_token")}"); var accessToken = ""; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await _httpClient.GetAsync($"/api/values"); if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine(response.StatusCode); Console.WriteLine((await response.Content.ReadAsAsync<HttpError>()).ExceptionMessage); } Console.WriteLine(await response.Content.ReadAsStringAsync()); Assert.Equal(HttpStatusCode.OK, response.StatusCode); }
public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider { public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (!context.TryGetBasicCredentials(out clientId, out clientSecret)) { context.TryGetFormCredentials(out clientId, out clientSecret); }
if (clientId != "xishuai") { context.SetError("invalid_client", "client is not valid"); return; } context.Validated(); }
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { if (string.IsNullOrEmpty(context.UserName)) { context.SetError("invalid_username", "username is not valid"); return; } if (string.IsNullOrEmpty(context.Password)) { context.SetError("invalid_password", "password is not valid"); return; }
if (context.UserName != "xishuai" || context.Password != "123") { context.SetError("invalid_identity", "username or password is not valid"); return; }
var OAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType); OAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); context.Validated(OAuthIdentity); } }
public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider { public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (!context.TryGetBasicCredentials(out clientId, out clientSecret)) { context.TryGetFormCredentials(out clientId, out clientSecret); }
if (clientId != "xishuai" || clientSecret != "123") { context.SetError("invalid_client", "client or clientSecret is not valid"); return; } context.Validated(); }
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)));
[Fact] public async Task OAuth_ClientCredentials_Test() { var tokenResponse = GetToken("client_credentials").Result; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
var response = await _httpClient.GetAsync($"/api/values"); if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine(response.StatusCode); Console.WriteLine((await response.Content.ReadAsAsync<HttpError>()).ExceptionMessage); } Console.WriteLine(await response.Content.ReadAsStringAsync()); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Thread.Sleep(10000);
var tokenResponseTwo = GetToken("refresh_token", tokenResponse.RefreshToken).Result; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponseTwo.AccessToken); var responseTwo = await _httpClient.GetAsync($"/api/values"); Assert.Equal(HttpStatusCode.OK, responseTwo.StatusCode); }