I am using below method to get token but sometimes (not every time) it returns null.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Generating the instance ID token may take some time. This means that while the initial token is being generated,FirebaseInstanceId.getInstance().getToken() will return null that is expected behavior.
If you want to capture when the initial token gets generated, as well as when the token is refreshed, have a look at monitoring the token. This means you'll need to implement a service, since the token may be refreshes while your app isn't active.
Related
I'm creating an application in next.js and using the next-auth package for the login access process.
I'm trying to add a new "apiToken" key that I get from my api, to the session cookie created by next-auth after performing an oauth login.
I'm doing it as follows: in the "signIn" callback I'm creating "user.apiToken" and passing the token I get from my api, in the "jwt" callback I try to create "token.apiToken" and pass the value of
"user.apiToken" so that it can retrieve this value in the "session" callback and thus write this value to the session cookie.
The problem is that for some reason I don't know, the application goes through the "jwt" callback twice, the first time I have all the user values, but the second time user comes with an undefined value, giving me an error in the application.
Has anyone gone through this problem? Or could you help me with a solution?
I managed to solve it, I just created a conditional block inside the session return "jwt"
if(user && account.provider === 'facebook'){token.apiToken =
user.apiToken}
So I can retrieve token.apiToken inside "session" callback without getting errors
I have SPA developed application on which I used to implement Oidc-Client for OAUTH authentication and below are the clarifications.
How to configure silent-refresh page with web pack config file in angular structure based project since silent-refresh.html is not invoked on token expiration.
Even if silent token generated then how to get/set expiration time of silently generated token?
Kindly help and suggest.
SILENT REFRESH
Rather than a separate HTML page, my personal preference is to handle this by a silent token renewal response to the index.html page. Then write code like this:
if (window.top === window.self) {
// Run the main app
const app = new App();
app.execute();
} else {
// If our SPA is running on an iframe, handle token renewal responses
const app = new IFrameApp();
app.execute();
}
I find that this approach avoids adding complexity to the WebPack / build system. The code for the iframe app does very little other than receiving the silent token renewal response.
EXPIRY
Interesting why you want to use access token expiry times directly. You can get the value like this:
const user = await this._userManager.getUser();
if (user) {
console.log(user.expires_at);
}
The real requirement here is to ensure that you avoid errors for end users when an API call fails due to an expired access token. This is best handled via the following actions:
If an API call fails with a 401 status code
Then try to get a new access token, generally via userManager.signInSilent()
Then retry the API call with the new access token
Therefore the way you call APIs should have a helper class with some retry logic, as in my example here.
To get notified after silent refresh, add an event handler for userLoaded: UserManager.events.addUserLoaded. This will pass the new User with a new expire time
I have implemented a mock service.it mock a async soap web service with call back result.When a request arrive with a unique id, mock service provide a response ("Prossesing") and store the requestid in a context like this (within Script):
context.put("requestid",mockerequest.requestid)
A call back is fired (from AfterScript) with stored requestid after few millisecond to show async behavior, using ThreadSleep .
From context, requestid is extracted like this,which is passed with callback result :
context.get("requestid")
It works fine with a single call. But when repeated requests are performed during load test, requestid
in the context is changed(next request is changing current requestid ) and a callback is fired with a wrong request id.It now problem to test multiple request in one go.
Do SoapUI support any kind of session variable, where value will be preserved for each session to avoid this problem ?
I am using the OWIN OAuthAuthorizationServer library in an OWIN ASP.NET C# web API to generate and process bearer tokens.
Right now, I have a single endpoint (which you set in the OAuthAuthorizationServerOptions struct) that accepts the grant_type, username and password fields from the frontend. I created a provider class that performs the validation, and then calls context.Validated() or context.SetError() accordingly. The middleware then handles generating the token and returning it to the user, and also "takes over" the login endpoint, doing all the work internally.
Now, I am adding a new feature to my API where the user can change their "role" (e.g. an admin can set themselves as a regular user to view the results of their work, a user can select among multiple roles, etc.) Since I already handle this through the bearer token (I store the user's role there and all my endpoints use the bearer token to determine the current role), I now have a reason to update the contents of the bearer token from the API backend.
What I'm looking to do is to allow the frontend to call an endpoint (e.g. api/set_role) that will accept a parameter. The user requests a certain role, and their current bearer token would accompany the request. The server then would check if the user in question is allowed to use that specific role and, if so, would generate a new token and return it to the user in the response body. The frontend would then update its token in local storage. Or, of course, if the user is not permitted to switch to that role, the backend would return an appropriate error and the frontend would react accordingly.
To do this I basically want to be able to manually generate a token. Similar to how I use identity.AddClaim() in my login provider, I'd like to be able to do that at any arbitrary position within the API's code. The method would take responsibility for transferring over any necessary existing information (e.g. the user's username) into the new token, since it already has the existing one.
Pseudocode for what I want:
if (!userCanUseRole(requestedRoleId)) return Request.CreateErrorResponse(...);
// we have a struct containing parsed information for the current token in the variable cToken
bearerToken newToken = new bearerToken();
newToken.AddClaim(new Claim("user", cToken.user));
newToken.AddClaim(new Claim("role", requestedRoleId));
string tokenToReturnToFrontend = newToken.getTokenString(); // string suitable for using in Authorization Bearer header
return Request.CreateResponse(new StringContent(tokenToReturnToFrontend));
I am not too familiar with "refresh" tokens, but the only way I am using them right now is extending token expiration. To that end the frontend explicitly requests a refresh token and provides its own, which the backend simply copies to a new token and edits the expiry time. The problem with this is that there's a single method for getting a refresh token, and since I have now at least one other reason to refresh a token (and possibly, future developments could add even more reasons to change token contents at various times), I'd then have to deal with storing transient data somewhere (E.g. "when requesting a refresh token, what is the thing the user wanted to do? has it been too long since they requested to do that? etc.) It'd be much easier if I could simply generate a bearer token on demand in the same way that the OAuthAuthorizationServer itself does. (I know it uses the MachineKey to do this, but I don't know exactly how it does it, nor how I would go about doing what I'm trying to do.)
Of note: In another project I provided internal access to the OAuthBearerAuthenticationOptions class that is passed to the authorization server instance, and was able to use that to decode a bearer token inside of a test. I haven't seen anything obvious thought that would let me encode a bearer token this way.
EDIT: I explored the (extremely tersely, almost uselessly documented) OWIN namespace and found the AccessTokenFormat class which appears that it should do what I want. I wrote this code:
Microsoft.Owin.Security.AuthenticationTicket at = new Microsoft.Owin.Security.AuthenticationTicket(new ClaimsIdentity
{
Label="claims"
}
, new Microsoft.Owin.Security.AuthenticationProperties
{
AllowRefresh=true,
IsPersistent=true,
IssuedUtc=DateTime.UtcNow,
ExpiresUtc=DateTime.UtcNow.AddMinutes(5),
});
at.Identity.AddClaim(new Claim("hello", "world"));
string token = Startup.oabao.AccessTokenFormat.Protect(at);
return Request.CreateResponse(HttpStatusCode.OK, new StringContent(token, System.Text.Encoding.ASCII, "text/plain"));
which seems like it should work. (I again allow access to the OAuthBearerAuthenticationOptions class passed to the OAuthAuthorizationServer instance.) However, this code throws an ArgumentNull exception. The stacktrace indicates that it is writing to a BinaryWriter but the OWIN code is passing a null value to the Write method on the BinaryWriter.
Still have no solution.
I did figure out the code to make this work. One could argue I'm "not using OAuth right", but strictly, this code WILL accomplish what I want - to generate a token in code at any arbitrary point and get the string.
First, as I said, I have to provide access to the OAuthBearerAuthenticationOptions class instance. When the OAuth server initializes I'm guessing it populates this class with all of the various objects used for tokens. The key is that we do have access to Protect and Unprotect which can both encode and decode bearer tokens directly.
This code will generate a token assuming that oabao is the OAuthBearerAuthenticationOptions class that has been passed to the OAuthAuthorizationServer instance:
Microsoft.Owin.Security.AuthenticationTicket at = new Microsoft.Owin.Security.AuthenticationTicket(new ClaimsIdentity("Bearer", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"),
new Microsoft.Owin.Security.AuthenticationProperties
{
AllowRefresh = true,
IsPersistent = true,
IssuedUtc = DateTime.UtcNow,
ExpiresUtc = DateTime.UtcNow.AddDays(1) // whenever you want your new token's expiration to happen
});
// add any claims you want here like this:
at.Identity.AddClaim(new Claim("userRole", role));
// and so on
string token = oabao.AccessTokenFormat.Protect(at);
// You now have the token string in the token variable.
So I'm very new with HMAC authentication and I really don't know what I'm doing nor reading atm.
I've been trying to understand the following articles / links / discussions properly:
How to implement HMAC Authentication in a RESTful WCF API
http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/22/how-to-implement-hmac-authentication-on-a-restful-wcf-service.aspx
http://buchananweb.co.uk/security01.aspx
With that said I have a few questions:
Understanding the first link, if for example I have a loginAuthentication service created in .net and will be accessed from an iPhone app do I pass an unencrypted username (message) for this and should return just a true / false or should it return an encrypted string in which I will be using later on for other transactions (Delete, Insert services, etc)?
[ServiceContract]
public partial class LoginService
{
[OperationContract]
bool Authenticate(string username) {
// stuffs
}
}
With that said, after I verified the user, and this is where I get lost. Is it better that I save something in the database 'with a timestamp' (someone told me about this and I read some discussions about this too)? Or do I just return it with the encrypted message (dependent on the first question) so that everytime a request is made the timestamp is already attached?
a. And what do I do with that timestamp?
b. Is it going to be used once the message is sent again for another transaction?
Keys and secret message. The way I understood it is that the key will be the password of the user. So if the user sends his username I can open the message using the password of that user? This makes sense if the user already has a session and is just requesting to get data or requesting for a delete, insert, etc. Should it still be the same way if it's just authenticating the username and password of the user?
Thank you for your time!
The first thing I would like to mention is that the WCF Web Api was a beta project which is no longer being developed. It was replaced by ASP.NET Web API which is an awesome framework for developing RESTful services.
If you want to get a good idea how a RESTful service and authentication works the Netflix API would be a great place to start. They have a lot of documentation regarding the security portion and this helped me understand HMAC a lot more.
HMAC creates a hash using a secret key. The client and server both maintain a copy of the secret key so that they can generate matching hashes. This allows you to 'sign' a request which serves as both authentication (you know the person sending it is who they say they are), and message integrity (knowing the message they sent is the original message and has not been tampered with).
A signature is created by combining
1. Timestamp (unix epoc is the easiest to send in urls)
2. Nonce (a random number that can never be used twice to protect against someone re-using it)
3. Message (for a GET request this would be the URL, a POST would be the whole body)
4. Signature (the three previous items combined and hashed using the secret key)
Each of the above can be sent in the query string of the request, then the server can use the first 3 and their copy of the secret key to recreate the signature. If the signatures match then all is good.
In a RESTful API that is over plain HTTP (not using HTTPS over an ssl), I would sign every request sent because again this authenticates and provides message integrity. Otherwise if you just send an authentication token you know the user is authenticated but how do you know the message was not tampered with if you do not have a Message Digest (the HMAC hash) to compare with?
An easy way to implement the server-side checking of the signature is to override OnAuthorization for System.Web.Http.AuthorizeAttribute (Make sure not to use Mvc autorize attribute). Have it rebuild the signature just as you did on the client side using their secret key, and if it does not match you can return a 401. Then you can decorate all controllers that require authentication with your new authorize attribute.
Hopefully this helps clear up some of your confusion and does not muddy the water even further. I can provide some more concrete examples later if you need.
References:
Netflix Api Docs: http://developer.netflix.com/docs/Security#0_18325 (go down to the part about creating signatures, they also have a link which shows a full .NET example for creating the HMAC signature)
.NET class for creating HMAC signatures http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs
Netflix API Wrapper I wrote: https://bitbucket.org/despertar1318/netflix-api/overview
ASP.NET Web API: http://www.asp.net/web-api
Looking at your questions in turn
...do I pass an unencrypted username (message) for this and should return just a true / false or should it return an encrypted string in which I will be using later on for other transactions (Delete, Insert services, etc)?
If you just returned a boolean, you'd have no way to then match the authentication request to subsequent requests. You'll need to return some sort of authentication indicator, on a classic website this would be the session cookie, in your instance you want to pass a value that will act as shared key.
Is it better that I save something in the database 'with a timestamp'? Or do I just return it with the encrypted message so that everytime a request is made the timestamp is already attached?
Back to the session analogy, you want to store the key from question one somewhere (the database?) with a timestamp that indicates the life of the session/validity of the key. If it's forever then I wouldn't bother with the timestamp, if it's anything else you'll need something to say when it expires.
The way I understood it is that the key will be the password of the user. So if the user sends his username I can open the message using the password of that user? This makes sense if the user already has a session and is just requesting to get data or requesting for a delete, insert, etc. Should it still be the same way if it's just authenticating the username and password of the user?
This is where the HMACing happens. You have your shared secret, you have a message, this is how I usually combine it all together.
Use all of the message as the body of data to be hashed (that way you can be sure that someone's not just copied the hash and part of the message). Hash the body of the message using the key we shared in step one. You could salt this if wanted, I'd use the username.
Finally make sure the message contains a timestamp (UTC preferably), this way you can help prevent replaying the message later. The service that's responding to the message can compare the timestamp to what it thinks the time is. If it falls outside given bounds, fail the message. Because the timestamp will be part of the HMAC, someone can't just update the date and replay the message, the hashes won't match as soon as the message is tampered with.