Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
using System;
using System.Net;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using SImpl.Http.OAuth.AspNetCore.WebApi.RequestModels;
using SImpl.Http.OAuth.AspNetCore.WebApi.ResponseModels;
using SImpl.OAuth.Constants;

namespace SImpl.Http.OAuth.AspNetCore.WebApi
{
[ApiController]
[Route("TaggingService/[controller]")]
[Route("oauth")]
public class OAuthRevokeTokenController : ControllerBase
{
private readonly IOAuthRefreshTokenStorage _oAuthRefreshTokenStorage;
Expand All @@ -24,64 +21,45 @@ public OAuthRevokeTokenController(
_oAuthClientStorage = oAuthClientStorage;
}

[Route("oauth/revoke")]
[HttpPost]
public HttpResponseMessage Revoke([FromBody] OAuthRevokeTokenRequest revokeRequest)
[HttpPost("revoke")]
public new IActionResult Revoke([FromBody] OAuthRevokeTokenRequest revokeRequest)
{
if (string.IsNullOrWhiteSpace(revokeRequest.ClientId)
|| string.IsNullOrWhiteSpace(revokeRequest.ClientSecret)
|| string.IsNullOrWhiteSpace(revokeRequest.Token))
{
return new HttpResponseMessage(HttpStatusCode.BadRequest)
return BadRequest(new OAuthTokenErrorResponse(OAuthTokenErrors.InvalidRequest)
{
Content = new StringContent(JsonConvert.SerializeObject(
new OAuthTokenErrorResponse(OAuthTokenErrors.InvalidRequest)
{
ErrorDescription = "client_id, client_secret and token is required."
}))
};
ErrorDescription = "client_id, client_secret and token is required."
});
}

var client = _oAuthClientStorage.Fetch(revokeRequest.ClientId);

if (client == null
if (client == null
|| client.ClientSecret != revokeRequest.ClientSecret)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(JsonConvert.SerializeObject(
new OAuthTokenErrorResponse(OAuthTokenErrors.InvalidClient)))
};
return BadRequest(new OAuthTokenErrorResponse(OAuthTokenErrors.InvalidClient));
}

try
{
if (revokeRequest.TokenTypeHint != OAuthTokenTypes.RefreshToken)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(JsonConvert.SerializeObject(
new OAuthTokenErrorResponse("unsupported_token_type")))
};
return BadRequest(new OAuthTokenErrorResponse("unsupported_token_type"));
}

_oAuthRefreshTokenStorage.Delete(revokeRequest.Token);

return new HttpResponseMessage(HttpStatusCode.OK);
return Ok();
}
catch (Exception e)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest)
return BadRequest(new OAuthTokenErrorResponse()
{
Content = new StringContent(JsonConvert.SerializeObject(
new OAuthTokenErrorResponse()
{
ErrorDescription = e.Message
}))
};
ErrorDescription = e.Message
});
}
}


}
}
92 changes: 37 additions & 55 deletions src/SImpl.Http.OAuth/AspNetCore/WebApi/OAuthTokenController.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using SImpl.Http.OAuth.AspNetCore.WebApi.RequestModels;
using SImpl.Http.OAuth.AspNetCore.WebApi.ResponseModels;
using SImpl.Http.OAuth.Models;
Expand All @@ -13,6 +10,7 @@
namespace SImpl.Http.OAuth.AspNetCore.WebApi
{
[ApiController]
[Route("oauth")]
public class OAuthTokenController : ControllerBase
{
private readonly IOAuthClientService _oAuthClientService;
Expand All @@ -35,9 +33,8 @@ public OAuthTokenController(
_oAuthRefreshTokenStorage = oAuthRefreshTokenStorage;
}

[Route("oauth/token")]
[HttpPost]
public HttpResponseMessage Token([FromBody]OAuthTokenRequest tokenRequest)
[HttpPost("token")]
public new IActionResult Token([FromBody] OAuthTokenRequest tokenRequest)
{
HttpContext.Response.Headers.Add("Cache-Control", "no-store");
HttpContext.Response.Headers.Add("Pragma", "no-store");
Expand All @@ -49,38 +46,29 @@ public HttpResponseMessage Token([FromBody]OAuthTokenRequest tokenRequest)
tokenRequest.GrantType);
if (client == null)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(JsonConvert.SerializeObject(new OAuthTokenErrorResponse(OAuthTokenErrors.InvalidClient)))
};

return BadRequest(new OAuthTokenErrorResponse(OAuthTokenErrors.InvalidClient));
}

switch (tokenRequest.GrantType)
var answer = tokenRequest.GrantType switch
{
case OAuthGrantTypes.Password:
return ProcessPasswordGrant(client, tokenRequest);
case OAuthGrantTypes.RefreshToken:
return ProcessRefreshTokenGrant(client, tokenRequest);
}
var answer = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(JsonConvert.SerializeObject( new OAuthTokenErrorResponse(OAuthTokenErrors.InvalidGrant)))
OAuthGrantTypes.Password => ProcessPasswordGrant(client, tokenRequest),
OAuthGrantTypes.RefreshToken => ProcessRefreshTokenGrant(client, tokenRequest),
_ => BadRequest(new OAuthTokenErrorResponse(OAuthTokenErrors.InvalidGrant))
};

return answer;

}

private HttpResponseMessage ProcessPasswordGrant(OAuthClient client, OAuthTokenRequest tokenRequest)
private IActionResult ProcessPasswordGrant(OAuthClient client, OAuthTokenRequest tokenRequest)
{
var scopes = (tokenRequest.Scopes ?? "")
.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries)
.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)
.ToList();

if (!_oAuthUserProvider.ValidateUser(tokenRequest.Username, tokenRequest.Password, scopes))
{
// User is invalid
return new HttpResponseMessage(HttpStatusCode.Forbidden);
return Forbid();
}

// Get claims
Expand All @@ -93,35 +81,32 @@ private HttpResponseMessage ProcessPasswordGrant(OAuthClient client, OAuthTokenR

var accessTokenExpiresIn = _oAuthAccessTokenService.GetAccessTokenLifetimeSeconds(client);
var accessToken = _oAuthAccessTokenService.GenerateAccessToken(claimsIdentity, client);
var refreshToken = _oAuthRefreshTokenService.GenerateRefreshToken(Request,userId, client, scopes);
var refreshToken = _oAuthRefreshTokenService.GenerateRefreshToken(Request, userId, client, scopes);

// Persist refresh token
_oAuthRefreshTokenStorage.Save(refreshToken);
var answer = new HttpResponseMessage(HttpStatusCode.OK)

return Ok(new OAuthTokenResponse
{
Content = new StringContent(JsonConvert.SerializeObject(new OAuthTokenResponse
{
TokenType = OAuthTokenTypes.Bearer,
AccessToken = accessToken,
RefreshToken = refreshToken.Token,
ExpiresIn = accessTokenExpiresIn,
Scope = string.Join(" ", scopes),
}))
};
return answer;
TokenType = OAuthTokenTypes.Bearer,
AccessToken = accessToken,
RefreshToken = refreshToken.Token,
ExpiresIn = accessTokenExpiresIn,
Scope = string.Join(" ", scopes),
});
}

private HttpResponseMessage ProcessRefreshTokenGrant(OAuthClient client, OAuthTokenRequest tokenRequest)
private IActionResult ProcessRefreshTokenGrant(OAuthClient client, OAuthTokenRequest tokenRequest)
{
// Validate refresh token
var refreshToken =
_oAuthRefreshTokenService.FindValidRefreshToken(tokenRequest.ClientId, tokenRequest.RefreshToken);
if (refreshToken == null)
{
// Refresh token is invalid
return new HttpResponseMessage(HttpStatusCode.Forbidden);
return Forbid();
}

// Get claims
var claims = _oAuthUserProvider.GetClaimsByUserId(refreshToken.UserId);

Expand All @@ -132,26 +117,23 @@ private HttpResponseMessage ProcessRefreshTokenGrant(OAuthClient client, OAuthTo
var accessTokenExpiresIn = _oAuthAccessTokenService.GetAccessTokenLifetimeSeconds(client);
var accessToken = _oAuthAccessTokenService.GenerateAccessToken(claimsIdentity, client);
var newRefreshToken = _oAuthRefreshTokenService.GenerateRefreshToken(Request,
refreshToken.UserId,
client,
refreshToken.UserId,
client,
tokenRequest.Scopes
?.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.ToList());
?.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.ToList());

// Persist refresh new token and delete old
_oAuthRefreshTokenStorage.Delete(refreshToken.Token);
_oAuthRefreshTokenStorage.Save(newRefreshToken);
var answer = new HttpResponseMessage(HttpStatusCode.OK)

return Ok(new OAuthTokenResponse
{
Content = new StringContent(JsonConvert.SerializeObject(new OAuthTokenResponse
{
TokenType = OAuthTokenTypes.Bearer,
AccessToken = accessToken,
RefreshToken = newRefreshToken.Token,
ExpiresIn = accessTokenExpiresIn,
}))
};
return answer;
TokenType = OAuthTokenTypes.Bearer,
AccessToken = accessToken,
RefreshToken = newRefreshToken.Token,
ExpiresIn = accessTokenExpiresIn,
});
}
}
}
}