What I'm trying to achieve is, using Raygun (a crash reporting service), send the user details of the user who experienced the issue.
I originally tried using a method similar to this to get the username:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
username = authentication.getName();
But for some reason this returned the value, ipaduser
. I'm not sure where that value comes from but this obviously isn't the answer.
I then tried:
System.getProperty("user.name");
But this just gets the name of the logged in user for our API server, not the username of the user using the application.
After some digging around, I discovered that the username and name of the database for a user is being stored in a custom object called ApiAccessToken. The problem is, that this ApiAccessToken object is only being set in methods in our Controller classes.
For instance:
@RequestMapping(path = "/api/foo", method = RequestMethod.GET)
public List<Bar> getBarForDatabase(@RequestParam(value = "api_key") String apiKey{
ApiAccessToken accessToken = validateApiKey(apiKeyService, apiKey);
// Etc
}
The code for ApiAccessToken and validateApiKey() are as follows:
public final class ApiAccessToken {
private String databaseName;
private String username;
public String getDatabaseName() { return databaseName; }
public void setDatabaseName(String databaseName) { this.databaseName = databaseName; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
}
And
protected ApiAccessToken validateApiKey(ApiKeyService apiKeyService, String apiKey){
UserAccountJdbcRepository userAccountJdbcRepository = new UserAccountJdbcRepository(createDataSourceForDatabase(USERS_DATABASE_NAME));
ApiAccessToken accessToken = apiKeyService.validateApiKey(userAccountJdbcRepository, apiKey);
if (accessToken == null) {
throw new InvalidApiKeyException();
}
return accessToken;
}
My other idea was having a local variable in the Controller class that would store the value of apiKey
and then I would pass that value to the other method using a getter. For example, in the Controller class:
private static String apiKey;
public static String getApiKey() { return apiKey; }
@RequestMapping(path = "/api/foo", method = RequestMethod.GET)
public List<Bar> getBarForDatabase(@RequestParam(value = "api_key") String apiKey{
ApiAccessToken accessToken = validateApiKey(apiKeyService, apiKey);
apiKey = this.apiKey;
//Etc
}
And then in the class where I'm sending exception details to Raygun:
String apiKey = Controller.getApiKey();
ApiAccessToken accessToken = validateApiKey(apiKeyService, apiKey);
username = accessToken.getUsername();
database = accessToken.getDatabaseName();
But that just returns a NullPointerException and doesn't send anything to Raygun.
Any help would be greatly appreciated as I'm not entirely sure what else to try. Let me know if there's anything I've left out that you think I should include. Once again, I'm still pretty new to Spring MVC and the developer who wrote most of this is no longer employed with us.