OpenIddict Refresh Token Flow issue ASP.NET Core - asp.net-core

I am trying to set my refresh token life time to 2 weeks. I have tried via .. FromSeconds, FromMinutes, FromHours, but it always sets the refresh token to the same lifetime as the access token. I would appreciate any help. This is what I currently have in my configureServices:
services.AddOpenIddict(options =>
{
// Register the Entity Framework stores.
options.AddEntityFrameworkCoreStores<AppDbContext>();
// Register the ASP.NET Core MVC binder used by OpenIddict.
// Note: if you don't call this method, you won't be able to
// bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
options.AddMvcBinders();
// Enable the token endpoint.
options.EnableTokenEndpoint("/connect/token");
// Enable the password flow.
options.AllowPasswordFlow()
.AllowRefreshTokenFlow()
.SetAccessTokenLifetime(TimeSpan.FromMinutes(1))
.SetRefreshTokenLifetime(TimeSpan.FromMinutes(20160));
// During development, you can disable the HTTPS requirement.
options.DisableHttpsRequirement();
});

Please note: the following post won't resolve the issue:
http://kosmisch.net/Blog/DotNetEssential/Archive/2017/9/11/openiddict-refresh-token-flow-issue-aspnet-core-20.html
Latest summary about the issue:
When login with user name and password, the following data is inserted into openiddicttoken table:
Id ApplicationId AuthorizationId Ciphertext End Hash Start Status Subject Type
1 NULL NULL NULL 2017-10-12 11:24:26.0000000 +00:00 NULL 2017-09-12 11:24:26.0000000 +00:00 valid 1 refresh_token
Then a refresh_token grant type request was done.
The above record is updated with only change is the Status column, which has changed from valid to redeemed
Id ApplicationId AuthorizationId Ciphertext End Hash Start Status Subject Type
1 NULL NULL NULL 2017-10-12 11:24:26.0000000 +00:00 NULL 2017-09-12 11:24:26.0000000 +00:00 redeemed 1 refresh_token
And the response JSON doesn't include the new refresh token attribute.
I think for the second refresh, I thought at least one of the Start or End column should change since I configured to use sliding expiration.
But it is not the case. So I think there might be one issue with this refresh token method. Could you please have a look?
In the example: https://github.com/openiddict/openiddict-samples/tree/dev/samples/RefreshFlow
I downloaded and I can see each time when a refresh is done, a new token will be inserted, which is very different from the behaviour I had. BTW, I have changed the sample code to use slide expiration as well.
The main difference is my model is using int as TKey while the sample is using GUID. So I am wondering whether this is something to do with that?
options.UseOpenIddict<int>();
Found out the root cause for my issue:
// Create a new authentication ticket holding the user identity.
var ticket = new AuthenticationTicket(principal, *new AuthenticationProperties(),* OpenIdConnectServerDefaults.AuthenticationScheme);
While it should be:
// Create a new authentication ticket holding the user identity.
var ticket = new AuthenticationTicket(principal, properties, OpenIdConnectServerDefaults.AuthenticationScheme);

Related

Update logged Identity claims when add new claims

I have a .net core web api application with angular. I use AspNetCore Identity. I have a claim table with userId and value colums. The createnewuser method call from angular site, and they call to register user method. There no any problem here.
I wanna add new claim into httpcontext current user claims list.
I'd tried but it is not help me.
Added a claim to an existing HttpContext User
But I can see added new claim into _httpContext.HttpContext.User.Claims when re-authenticate with new token. How can I see add new claim into current identity (_httpContext.HttpContext.User.Claims)?
And I got current user Id value from httpontext.
var parentId = _httpContext.HttpContext.User.Claims?.FirstOrDefault(p => p.Type == "uid");
if (parentId != null && parentId.Value != null)
{
await _IdentityService.AddClaimAsync(new RegisterRequest()
{
"newclaim" = "new-claim-key",
userId = parentId.Value
});
I think best wasy get claims from db who logged used like that:
var claimList = userManager.
GetClaimsAsync(await_userManager.GetUserAsync(_httpContext.HttpContext.User))
Although this is not a very accurate method, it is the most reliable method. This way you can get the latest claim list in db

updateTenants not working after token refreshed

I'm in the process of updating our app from from oauth 1 to 2. Entire flow works well - I can migrate and save the tokens and access the APIs. However, there is a problem once the original token expires and it gets refreshed. After refreshing, the call to updateTenants does not return any active connections.
My pseudocode is below:
const tokenSet = await getTokenSet(); // Returns saved token set from DB. Assume token is expired!!
const client = new XeroClient(...);
client.setTokenSet(tokenSet);
const newToken = await client.refreshToken();
await saveTokenSet(newToken); // Save to DB
const token = client.readTokenSet();
console.log(token); // Does return my NEW active token set
const tenants = await client.updateTenants(false);
console.log(tenants.body); // This returns an array of length 0
Not clear why the results from updateTenants is empty. I was able to verify this by calling the GET https://api.xero.com/connections endpoint manually with one of the refreshed tokens and also see an empty array in the body.
Any ideas?
I played around with our xero-node-oauth2-app to see if I could recreate this. Here's what I found:
If I connected to my Xero org to obtain valid tokens and then disconnected via the Xero connected apps dashboard and then refreshed my tokens triggering updateTenants the connections endpoint returns an empty array and status code 200. In other words, it's a successful call but Xero doesn't see that the user has authorized your integration to interact with any of their orgs/tenants.
Are you able to verify if your integration is still listed in the connected apps list under settings?
https://community.xero.com/developer/discussion/127403806

Cookie Authentication: How to access a returning user

I have studied a couple examples of ASP.Net Core 2.0 Cookie Authentication.
However, I still don't see the code that checks for a returning user via a cookie.
Please note that I'm not a web developer. As a result, I realize that my question may appear foolish.
As I understand, the browser sends the cookie to the server per client request. However, I just don't see the server logic for this in the examples that I've studied. Hence, I only see logic for logging in the user the very first time based a username and password that's explicitly passed in.
Expectation:
I expected the server to explicitly check if a cookie exists when requesting the index page of the website. If a cookie does exist, I would expect to see some logic to address a user that's already logged in.
Giraffe example
Tutorial example
Here's my code:
let loginHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
Tasks.Task.Run(fun _ -> StackOverflow.CachedTags.Instance() |> ignore) |> ignore
task {
let! data = ctx.BindJsonAsync<LogInRequest>()
let email = data.Email.ToLower()
if authenticate email data.Password
then match login email with
| Some provider ->
let claims = [ Claim(ClaimTypes.Name, email) ]
let identity = ClaimsIdentity(claims, authScheme)
let user = ClaimsPrincipal(identity)
do! ctx.SignInAsync(authScheme, user)
return! json provider next ctx
| None -> return! (setStatusCode 400 >=> json "Invalid login") next ctx
else return! (setStatusCode 400 >=> json "Invalid login") next ctx
}
I'm looking at the giraffe example.
The statements services.AddAuthentication(authScheme) and services.AddCookie(cookieAuth) will add various services to the services collection, making them available for injection.
The statement app.UseAuthentication() adds services to the middleware pipeline. A middleware service is something that runs on every request.
The service that gets added by UseAuthentication is called AuthenticationMiddleware. As you can see this middleware relies on an injected IAuthenticationSchemeProvider (provided by your call to AddAuthentication) which in turn (skipping a few steps here) relies on a service called CookieAuthenticationhandler (provided by your call to AddCookie) which actually does the work of authenticating via cookie. When it is done it sets the logged in user onto the HttpContext which you can reference from your controllers if you need to.

RESTful API using JWT (JSON Web Token) setup token expiry

I'm using JWT for RESTful API (Laravel Web-Services for mobile). How to setup token expiry to never expiry or what the best practice to setup token expiry?
Because currently i need to get the token everytime when the token expired, can anybody have this issue or best solution for token expiry.
There is nothing to make the token never expire. However you can extend the expiration date to a very huge time span, 1 year for example. This is possible, however it is not recommended for security.
In order to achieve that, you need to configure two parts, the token refresh time, and token expiry.
So in config/jwt.php
'refresh_ttl' => 29030400, // Number of minutes in 1 year (12*4*7*24*60*60)
And when you are creating your token, you can pass something like the following
$tokenId = base64_encode(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
$issuedAt = Carbon::now()->timestamp;
$notBefore = $issuedAt; //Adding 10 seconds
$expire = $notBefore + 12*4*7*24*60*60; // Adding 6 hours
/*
* Create the token as an array
*/
$data = [
'iat' => $issuedAt, // Issued at: time when the token was generated
'jti' => $tokenId, // Json Token Id: an unique identifier for the token
'iss' => 'https://example.com', // Issuer
'nbf' => $notBefore, // Not before
'exp' => $expire, // Expire
'data' => [ // Data related to the signed user
'userId' => Auth::user()->id, // userid from the users table
]
];
Now, your token will never expire before 1 year. And you have up to 1 year to refresh it. When the user opens the application the next time, and you authenticate the token, you can refresh it. You can refresh the token, as mentioned in the documentation here. I would recommend going through this laracasts discussion as well.
Also, I have found this question on StackOverflow, I think it will help.

DropboxUnlinkedException but the session already had token inside and user didn't revoke the access

My problem is I have existing user in database which store the key and secret from the first authentication. I wish to reuse it again when I come back. For the first time authentication, everything working fine. I can use every method call from Dropbox API and the Token(key and secret) was stored in database.
I come back to app and get the Token from database, set it to the session, link current session with API.
session = new WebAuthSession(appKeys, ACCESS_TYPE);
api = new DropboxAPI<WebAuthSession>(session);
String userKey = dropboxUserObj.getUserKey(); //Key from database
String userSecret = dropboxUserObj.getUserSecret();//Secret from database
AccessTokenPair userAccessTokenPair = new AccessTokenPair(userKey, userSecret);
session.setAccessTokenPair(userAccessTokenPair);
It return DropboxUnlinkedException to me when I want to get user data from api using
String userDisplayName = api.accountInfo().displayname;
I have checked on debug mode. Api was linked with the current session. The current session stored Appkey and user's token and correct access type. The point that I doubt is I saw "client = null". I maybe forgot something but I check them all, try every possibilities I can think of but it still return me "DropboxUnlinkedException" which mean I haven't set an access token pair on the session and I didn't revoke access for sure.
Please help me figure out...
I added a screenshot maybe it can illustrate my problem