Saving JWT token in static filed is best practice? - authentication

Saving KeyForHmacSha256, TokenIssuer, TokenAudience and TokenLifetimeMinutes in static filed is best practice or read these value from config file.
public class SecurityConstants
{
public static readonly byte[] KeyForHmacSha256 = new byte[64];
public static readonly string TokenIssuer = string.Empty;
public static readonly string TokenAudience = string.Empty;
public static readonly double TokenLifetimeMinutes = 1;
static SecurityConstants()
{
RNGCryptoServiceProvider cryptoProvider = new RNGCryptoServiceProvider();
cryptoProvider.GetNonZeroBytes(KeyForHmacSha256);
TokenIssuer = "issuer";
TokenAudience = "http://localhost:90";
}
}

As with about anything, the answer is "it depends."
I would certainly make the argument that the KeyForHmacSha256 variable is pulled from a config file or environment variable, just to keep it out of source control.
Personally, I usually pull in issuer and audience dynamically. The issuer is pulled from the environment so that I don't have to manually set it in each deploy and the audience is determined by who is requesting the token.
The token lifetime has the best case for just being a static definition. If you have a need to make it dynamic, you will need to handle that, but setting it explicitly isn't a security issue.

Related

signUpUrl returning nullpointerexception

SignupUrl signupUrl = androidManagementClient
.signupUrls()
.create()
.setProjectId(CLOUD_PROJECT_ID)
.setCallbackUrl(CALLBACKURL).execute();
causes the app to crash due to NPE
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.api.services.androidmanagement.v1.AndroidManagement$SignupUrls com.google.api.services.androidmanagement.v1.AndroidManagement.signupUrls()' on a null object reference
Has anyone seen this before? I've followed all the prerequisites to developing and am currently going of off the sample app, and this is the piece of code that crashes. What could be the reason?
https://developers.google.com/android/management/sample-app
Update as per request:
Code
EnterpriseHelperClass - I'd like to do this programmatically even though I know this can easily be executed via the quickstart guide.
public class EnterpriseCreationHelper {
private static final String CALLBACKURL =
"https://play.google.com/work/adminsignup?enterpriseToken";
private static final String TAG = "MainActivity";
private static String CLOUD_PROJECT_ID = "******-";
private static String SERVICE_ACCOUNT = "****#****-.iam.gserviceaccount.com";
private static String CREDENTIALS_FILE =
"/Users/****/appname/src/******.json";
private static String POLICY_ID = "samplePolicy";
private static AndroidManagement androidManagementClient;
public EnterpriseCreationHelper(AndroidManagement androidManagementClient){
EnterpriseCreationHelper.androidManagementClient = androidManagementClient;
}
public void run() throws IOException {
Your androidManagementClient value is null.
Kindly share the initialisation method of androidManagementClient it will be helpful for us to answer
Thanks
Looks like getAndroidManagementClient is returning a null object, which results in setting androidManagementClient to null. Make sure your credentials are correct, and that this method returns successfully.

Change AspNetCore2 Oauth redirect handler

TL;DR
How do I change the behaviour of the redirect_url endpoint? I want to process SAML which obviously isn't a JWT.
All the gory details
You've probably seen code like this
Microsoft.AspNetCore.Authentication.AuthenticationBuilder authBuilder;
authBuilder = services.AddAuthentication();
...
authBuilder.AddGitHub(gitHubOptions =>
{
gitHubOptions.AppId = clientId;
gitHubOptions.AppSecret = clientSecret;
});
Rummaging through the source code for the GitHub provider we find that AddGitHub is an extension method that looks like this
public static AuthenticationBuilder AddGitHub(
[NotNull] this AuthenticationBuilder builder,
[NotNull] Action<GitHubAuthenticationOptions> configuration)
{
return builder.AddGitHub(GitHubAuthenticationDefaults.AuthenticationScheme, configuration);
}
GitHubAuthenticationDefaults.AuthenticationScheme is just a string constant with the value "GitHub". If you want to re-use the same provider with more than one authentication endpoint then you have to use a different scheme name.
There's a succession of calls to signature overloads adding parameters and ending here.
public static AuthenticationBuilder AddGitHub(
[NotNull] this AuthenticationBuilder builder,
[NotNull] string scheme, [CanBeNull] string caption,
[NotNull] Action<GitHubAuthenticationOptions> configuration)
{
return builder.AddOAuth<GitHubAuthenticationOptions, GitHubAuthenticationHandler>(scheme, caption, configuration);
}
DisplayName also defaults to "GitHub" and isn't significant. Config we supplied above. So really we're calling AuthenticationBuilder.AddOAuth with two strings and our config object.
This call magically creates a redirection endpoint called signin-github which processes the token returned by the GitHub auth service.
The obvious next step is to clone the aspnet/Security repo, link a sample project to it and step through the magic, but naturally it targets Core 2.1 which everyone1 has.
More rummaging turns up this.
public static AuthenticationBuilder AddOAuth<TOptions, THandler>(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<TOptions> configureOptions)
where TOptions : OAuthOptions, new()
where THandler : OAuthHandler<TOptions>
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<TOptions>, OAuthPostConfigureOptions<TOptions, THandler>>());
return builder.AddRemoteScheme<TOptions, THandler>(authenticationScheme, displayName, configureOptions);
}
It's an awful lot of code to wade through. Can anyone tell me where and how the redirection handler endpoint is generated, and how one goes about providing replacement behaviour for it?
Line 89 of OAuthHandler.cs looks promising
var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath));
because this appears to be the logic that swaps the CODE for the tokens and it is overridable, but it's very difficult to be sure when I can't run it.
By "everyone" I mean everyone on the aspnetcore dev team, obviously.

Basic Sample (Java preferred) for Desire2Learn API

I have visited and read all the Valence, and specifically the REST API, pages. I have one approved key already and a second key that has not yet been approved by D2L, and it's not clear how I request that approval.
The documentation contains a lot of information, but it is difficult to put all the pieces together. For example, in order to make any REST API call, I have to add several parameters to the end of the call. The parameters are documented in one place, but it isn't clear in some cases how to construct them (for example, one of the keys is to contain the url, timestamp, and the type of call being made, but how are they to be concatenated?). Then they have to be signed, and the documentation that tells how to sign the keys is in a completely different page that is not even referenced from the page that tells you that you have to sign the parameters. On top of that, the documentation is not extremely clear about how to do the signing, and offers no further explanation or examples. So to get anywhere, we have to jump around a lot through the documentation, and go through a whole lot of trial and error. It appears that the documentation assumes that the reader has expertise in several areas, which may or may not be true.
Code examples would make a huge difference.
There aren’t a lot of samples yet; we are working to add more, and to make the ones that are present more obvious. As one example, there is a Java Android app that has all the authentication stuff and some basic calls (including the call “whoami” which is a great test call).
The specific auth related files are available as well. From the D2LSigner class, you can see the signing algorithm we use:
Mac hmacSha256 = Mac.getInstance("hmacSHA256");
byte[] keyBytes = key.getBytes("UTF-8");
Key k = new SecretKeySpec(keyBytes, "hmacSHA256");
hmacSha256.init(k);
byte[] dataBytes = data.getBytes("UTF-8");
byte[] sig = hmacSha256.doFinal(dataBytes)
String sigString = base64Url( sig );
From D2LOperationSecurityImpl, you can see how the query string fits together:
//uppercase METHOD, lowercase PATH, timestamp as string
private static /*final*/ String BASE_STRING_TEMPLATE = "{0}&{1}&{2}";
private static /*final*/ String APP_ID_QUERY_NAME = "x_a";
private static /*final*/ String APP_SIG_QUERY_NAME = "x_c";
private static /*final*/ String USER_ID_QUERY_NAME = "x_b";
private static /*final*/ String USER_SIG_QUERY_NAME = "x_d";
private static /*final*/ String TIMESTAMP_QUERY_NAME = "x_t";
...
#Override
public Uri createAuthenticatedUri(String path, String httpMethod) {
long timestamp = System.currentTimeMillis() +
mServerSkewCorrectionMillis.longValue();
Long timestampObjectSeconds = new Long(timestamp/1000);
Object[]formatParms = {httpMethod.toUpperCase(),
path.toLowerCase(),
timestampObjectSeconds.toString()};
String signatureBaseString = MessageFormat.format(BASE_STRING_TEMPLATE,
formatParms);
String appSig = D2LSigner.base64URLSig(mAppKey, signatureBaseString);
String userSig = D2LSigner.base64URLSig(mUserKey, signatureBaseString);
if ((appSig == null) || (userSig == null)) {
return null;
}
String scheme = mEncryptOperations?ENCRYPED_SCHEME:PLAIN_SCHEME;
Uri.Builder b = new Uri.Builder();
b.scheme(scheme);
b.authority(mHostName);
b.path(path);
b.appendQueryParameter(APP_ID_QUERY_NAME, mAppID);
b.appendQueryParameter(APP_SIG_QUERY_NAME, appSig);
b.appendQueryParameter(USER_ID_QUERY_NAME, mUserID);
b.appendQueryParameter(USER_SIG_QUERY_NAME, userSig);
b.appendQueryParameter(TIMESTAMP_QUERY_NAME, timestampObjectSeconds.toString());
Uri securedURI = b.build();
return securedURI;
}
Also, you need to sign the first URL you use for logging in, but only with the application key (because you haven't yet established a user context). It uses a different base string (to protect the URL that is used during auth):
String signature = D2LSigner.base64URLSig(mAppKey, resultURLString);
BasicNameValuePair appID = new BasicNameValuePair(APP_ID_NAME, mAppID);
BasicNameValuePair appSig = new BasicNameValuePair(APP_SIG_NAME, signature);
BasicNameValuePair callbackURL = new BasicNameValuePair(CALLBACK_NAME, resultURLString);

RavenDB - One client can't see changes from a different client

I'm running two instances of my application. In one instance, I save one of my entities. When I check the RavenDB (http://localhost:8080/raven), I can see the change. Then, in my other client, I do this (below), but I don't see the changes from the other application. What do I need to do in order to get the most recent data in the DB?
public IEnumerable<CustomVariableGroup> GetAll()
{
return Session
.Query<CustomVariableGroup>()
.Customize(x => x.WaitForNonStaleResults());
}
Edit: The code above works if I try to make a change and get a concurrency exception. After that, when I call refresh (which invokes the above code), it works.
Here is the code that does the save:
public void Save<T>(T objectToSave)
{
Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave);
Session.Store(objectToSave, eTag);
Session.SaveChanges();
}
And here is the class that contains the Database and Session:
public abstract class DataAccessLayerBase
{
/// <summary>
/// Gets the database.
/// </summary>
protected static DocumentStore Database { get; private set; }
/// <summary>
/// Gets the session.
/// </summary>
protected static IDocumentSession Session { get; private set; }
static DataAccessLayerBase()
{
if (Database != null) { return; }
Database = GetDatabase();
Session = GetSession();
}
private static DocumentStore GetDatabase()
{
string databaseUrl = ConfigurationManager.AppSettings["databaseUrl"];
DocumentStore documentStore = new DocumentStore();
try
{
//documentStore.ConnectionStringName = "RavenDb"; // See app.config for why this is commented.
documentStore.Url = databaseUrl;
documentStore.Initialize();
}
catch
{
documentStore.Dispose();
throw;
}
return documentStore;
}
private static IDocumentSession GetSession()
{
IDocumentSession session = Database.OpenSession();
session.Advanced.UseOptimisticConcurrency = true;
return session;
}
}
Lacking more detailed information and some code, I can only guess...
Please make sure that you call .SaveChanges() on your session. Without explicitly specifiying an ITransaction your IDocumentSession will be isolated and transactional between it's opening and the call to .SaveChanges. Either all operations succeed or none. But if you don't call it all your previous .Store calls will be lost.
If I was wrong, please post more details about your code.
EDIT: Second answer (after additional information):
Your problem has to do with the way RavenDB caches on the client-side. RavenDB by default caches every GET request throughout a DocumentSession. Plain queries are just GET queries (and no, it has nothing to do wheter your index in dynamic or manually defined upfront) and therefore they will be cached. The solution in your application is to dispose the session and open a new one.
I suggest you rethink your Session lifecycle. It seems that your sessions live too long, otherwise this concurrency wouldn't be an issue. If you're building a web-application I recommend to open and close the session with the beginning and the end of your request. Have a look at RaccoonBlog to see it implemented elegantly.
Bob,
It looks like you have but a single session in the application, which isn't right. The following article talks about NHibernate, but the session management parts applies to RavenDB as well:
http://archive.msdn.microsoft.com/mag200912NHibernate
This code is meaningless:
Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave);
Session.Store(objectToSave, eTag);
It basically a no op, but one that looks important. You seems to be trying to work with a model where you have to manually manage all the saves, don't do that. You only need to manage things yourself when you create a new item, that is all.
As for the reason you get this problem, here is a sample:
var session = documentStore.OpenSession();
var post1 = session.Load<Post>(1);
// change the post by another client
post2 = session.Load<Post>(1); // will NOT go to the server, will give the same instance as post1
Assert.ReferenceEquals(post1,post2);
Sessions are short lived, and typically used in the scope of a single form / request.

BlackBerry: How to use PersistableRIMKeyStore?

I need to securely store private user data so it can persist across my app starts as well as device resets.
This will be a String I guess about 1000 chars at maximum.
I was told I can use RIM KeyStore API for this.
Well, I spent hours googling out any gide on RIM KeyStore API usage. JDE samples do not contain anything useful on this.
Looks like this is a rare thing in BB development, so there's almost no official info on this.
I read this and this. From those I understood the best choice for me is to use PersistableRIMKeyStore (it persists across device resets). However I am not able to figure out what exactly should the implementation be.
Can anyone help with sample code or point me to some guide? Also maybe there's a better/simpler way/approach for my task, so, please, let me know about it.
Thanks a lot in advance!!!
If you use the store in the same was as the "PersistentStoreDemo" which if you don't know you can get by going to File -> Import -> Blackberry Samples, you can encrypt the info in the store. On top of this, if the user has content protection on, you can use a ContentProtectedHashtable to automatically know that that information would be encrypted. So, without content protection, the info would be encrypted once, with it on, it would be doubly encrypted as well as stored with a hard to guess long hash of the app namespace (obviously, since to register the store you need it). Below is what I use:
package ca.dftr.phillyd.lib.persistables;
import net.rim.device.api.system.ApplicationDescriptor;
import net.rim.device.api.util.ContentProtectedHashtable;
import net.rim.device.api.util.Persistable;
/**
* Basic class for storing application specific information.
* Information such as application settings or whether the license agreement was accepted.
* For more complex and specific classes they should be implemented separately and implement persistable
* #author deforbes
*/
public class AppInfo extends ContentProtectedHashtable implements Persistable {
private String _appName = null;
private String _version = null;
/**
* Constructs the application info, creates and persists a hashtable for application settings.
* #param uniqueHexAppIdentifier Can be automatically created in resource class (BUNDLE_ID) or generated using other unique information.
*/
public AppInfo() {
ApplicationDescriptor appDesc = ApplicationDescriptor.currentApplicationDescriptor();
_appName = appDesc.getName();
_version = appDesc.getVersion();
}
/**
* Get the Name of the application
* #return The application name from the app descriptor
*/
public String getName()
{
return _appName;
}
/**
* Get the Version of the application
* #return The application version from the app descriptor
*/
public String getVersion()
{
return _version;
}
}
Along with a class of constants (which could be included in the above if you want). For example, From my PhillyD app:
package ca.dftr.phillyd.lib.persistables;
/**
* Keys for the AppInfo array
* #author deforbes
*/
public class AppInfoKeys {
public static final String QUALITY = "Quality";
public static final String CHANNEL = "Channel";
public static final String CHANNEL_NAME = "Channel_Name";
public static final String SEARCH = "Search";
public static final String LICENSE_ACCEPTED = "isLicenseAccepted";
public static final String VIDEOS_PER_PAGE = "NumPerPage";
public static final Boolean DOWNLOAD_THUMBS = new Boolean(true);
}
The PersistableRIMKeyStore is used to persist the RIM Key Store. To persist user data accross resets you only need to use the PersistentStore, if you want the deta to be protected you could use the ContentProtectedHashtable or ContentProtectedVector.