I Could not retrieve the data from OwinContext Environment that I store it after authenticate by token.
this is the Code:
[ValidateClientAuthentication]
In thins Code I validate the ClientID of the User and then store the data of ApplicationClient in OwinContext in this line
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
...
ApplicationClient App = new ApplicationClient();
App.Id = clientId;
App.ClientSecretHash = clientSecret;
// Storing Client Data
context.OwinContext.Set<ApplicationClient>("oauth:client", App);
context.Validated(clientId);
}
[GrantResourceOwnerCredentials] Here I Validate User Credentials and Add Climes to the Token
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
...
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (Membership.ValidateUser(username, password))
{
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim(ClaimTypes.Name, username));
context.Validated(identity);
}
else
{
context.SetError("Login Field", "Error username or password");
}
}
[ControlerCode] Now Here is My Problem
[Authorize]
public class MyController : ApiController
{
public IEnumerable<SelectedMenu> GetAllMenus() // Resturants ID
{
// client is Null
ApplicationClient client = HttpContext.Current.GetOwinContext().Get<ApplicationClient>("oauth:client");
}
}
You should really only add the clientId
inside your token, so you may retrieve it anytime after the login process.
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
// ...
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (Membership.ValidateUser(username, password))
{
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim(ClaimTypes.Name, username));
identity.AddClaim(new Claim("oauth-client", context.ClientId));
context.Validated(identity);
}
else
{
context.SetError("Login Field", "Error username or password");
}
}
You may also create an extension method to help you in retrieving the clientId
:
public static class PrincipalExtensions
{
public static string GetClientId(this IPrincipal principal)
{
return (principal.Identity as ClaimsIdentity)?
.Claims
.FirstOrDefault(c => c.Type == "oauth-client")?
.Value;
}
}
And inside your controller:
[Authorize]
public class MyController : ApiController
{
public IEnumerable<SelectedMenu> GetAllMenus() // Resturants ID
{
var clientId = User.GetClientId();
}
}
Regarding the token size: if your clientId
string is too long I suggest you to use another one and store any other client information (including a longer id if is needed) inside the database. The client identifier should be a small and unique string easy to transmit.