How to fix apache shiro unknown session exception on logout action - oracle-adf

I have ADF web application developed using Jdeveloper 12.1.3 version, Glassfish server 3.1.2 version and Apache Shiro for security.
Login action and application security are working fine, but not logout action.
After logged out from application, it should be redirected to login page. But it throws
"javax.servlet.ServletException: java.lang.IllegalStateException:
org.apache.shiro.session.UnknownSessionException: There is no session
with id" error.
Logout action method code is
public String logout() throws IOException {
try {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
SecurityUtils.getSubject().logout();
} catch (Exception e) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "");
FacesContext.getCurrentInstance().addMessage(null, msg);
e.printStackTrace(); // TODO: logger.
}
return "";
}
Do I miss anything ?

It looks like you invalidating the session and then calling logout. Have you tried logging out first? Or something like:
Subject subject = SecurityUtils.getSubject();
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
subject.logout();
Otherwise, it looks like you are trying to get the current subject from an empty session.

Related

Twilio voice application error occurred

I am trying to integrate Twilio to my AngularJS and spring MVC application. After following Twilio documentation I set up at front end device setup and calling etc. In Java class I am generating a token, and passing that token while making the call. In java the code is:
#RequestMapping(value = "/phoneCalling", method {
RequestMethod.GET, RequestMethod.POST
})
public #ResponseBody Phone phoneCalling(HttpServletRequest request, HttpServletResponse response, #RequestParam String leadPhone) {
try {
Number number = new Number.Builder(leadPhone).build();
Dial dial = new Dial.Builder().number(number).build();
VoiceResponse responseVR = new VoiceResponse.Builder().dial(dial).build();
System.out.println(responseVR.toXml());
} catch (TwiMLException e) {
e.printStackTrace();
}
return null;
}
At twilio TwiML, I set request URL as:
https://865c048b.ngrok.io/ZingyCRM/phoneCalling/
As I am testing locally, so used ngrok. But after clicking on make a call, it gives me voice message as application error occurred. I believe the TwiML request URL I might be setting wrong, can some one help here?

access_denied when accessing Gmail API with auth scope https://mail.google.com/

I am trying to read/write emails/folders inside Gmail mailboxes using the Gmail REST API. When adding the following Google auth scopes, emails can be read from Gmail REST API without any problem:
https://apps-apis.google.com/a/feeds/compliance/audit/,
https://www.googleapis.com/auth/admin.directory.user.readonly, https://www.googleapis.com/auth/gmail.readonly,
https://www.googleapis.com/auth/admin.directory.group.member.readonly, https://www.googleapis.com/auth/admin.directory.group.readonly
Note: The parameter https://www.googleapis.com/auth/gmail.readonly correctly allows one to read from mailboxes.
However, I need to be able to delete emails too. Thus, in line with the documentation at https://developers.google.com/gmail/api/auth/scopes?hl=ja, one simply needs to include https://mail.google.com/ in place of https://www.googleapis.com/auth/gmail.readonly. When adding the following auth scopes:
https://apps-apis.google.com/a/feeds/compliance/audit/,
https://www.googleapis.com/auth/admin.directory.user.readonly, https://mail.google.com/,
https://www.googleapis.com/auth/admin.directory.group.member.readonly, https://www.googleapis.com/auth/admin.directory.group.readonly
... the error outputted is as follows:
2015-07-27 10:27:59 i.c.s.a.cv [DEBUG] failed get labels for user
com.google.api.client.auth.oauth2.TokenResponseException: 403 Forbidden
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
Surely, this is incorrect on the part of Google? What am I missing? Is the documentation incorrect? What auth scope needs to be added?
I am interfacing with the Java Google API Client Library. See: https://developers.google.com/api-client-library/java/google-api-java-client/reference/1.20.0/overview-summary
The delete request is as follows:
public void deleteMessages(Queue<String> messages, GoogleUserAdapter user) throws Exception {
Gmail gmail = getService(user);
JsonBatchCallback<Void> voidCallBack = new JsonBatchCallback<Void>() {
#Override
public void onSuccess(Void t, HttpHeaders responseHeaders) throws IOException {
logger.debug("delete success");
}
#Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) throws IOException {
logger.debug("failed to delete message:"+e.getMessage());
}
};
while (!messages.isEmpty()) {
if (Thread.currentThread().isInterrupted())
throw new InterruptedException();
BatchRequest batch = gmail.batch();
for (int i = 0; i < MAX_REQUESTS; i++) {
if (messages.isEmpty() || Thread.currentThread().isInterrupted())
break;
gmail.users().messages().delete(user.getId(), messages.poll()).queue(batch, voidCallBack);
}
batch.execute();
}
}
The credential is created as follows:
private GoogleCredential getCredentials(JsonFactory jsonFactory, HttpTransport httpTransport, String impersonateAccount) throws Exception {
Preconditions.checkNotNull(Strings.emptyToNull(impersonateAccount), "Google impersonate account is null");
Preconditions.checkNotNull(Strings.emptyToNull(connection.getServiceAccountId()), "Service Account Email address is null");
Preconditions.checkNotNull(connection.getServiceAccountPrivateKey(), "Service Account Private Key is null");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(connection.getServiceAccountId())
.setServiceAccountScopes(
Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, GmailScopes.MAIL_GOOGLE_COM,
"https://apps-apis.google.com/a/feeds/compliance/audit/",
DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY,
DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY))
.setServiceAccountUser(impersonateAccount)
.setServiceAccountPrivateKey(connection.getServiceAccountPrivateKey().getPrivateKey())
.build();
setHttpTimeout(credential);
return credential;
}
The exact error that occurs on delete is:
failed to delete message:Insufficient Permission
Jamie
Access denied is caused by a typo in the constant GmailScopes.MAIL_GOOGLE_COM as defined by the Google Java Client API.
The constant returns "https://mail.google.com" and not "https://mail.google.com/" (as it ought to be). Omitting a backslash at the end of the string will result in access denied.
Thus, in the example above, the following service scopes must be set:
https://apps-apis.google.com/a/feeds/compliance/audit/","https://mail.google.com/",DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY, DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY
(note: the hardcoded value of "https://mail.google.com/")
The following string must be added to Manage API client access page in Google Apps:
https://apps-apis.google.com/a/feeds/compliance/audit/,
https://www.googleapis.com/auth/admin.directory.user.readonly, https://mail.google.com/,
https://www.googleapis.com/auth/admin.directory.group.member.readonly, https://www.googleapis.com/auth/admin.directory.group.readonly
I hope this helps someone else!
private GoogleCredential getCredentials(JsonFactory jsonFactory, HttpTransport httpTransport, String impersonateAccount) throws Exception {
Preconditions.checkNotNull(Strings.emptyToNull(impersonateAccount), "Google impersonate account is null");
Preconditions.checkNotNull(Strings.emptyToNull(connection.getServiceAccountId()), "Service Account Email address is null");
Preconditions.checkNotNull(connection.getServiceAccountPrivateKey(), "Service Account Private Key is null");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(connection.getServiceAccountId())
.setServiceAccountScopes(
Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, GmailScopes.MAIL_GOOGLE_COM,
"https://apps-apis.google.com/a/feeds/compliance/audit/",
DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY,
DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY))
.setServiceAccountUser(impersonateAccount)
.setServiceAccountPrivateKey(connection.getServiceAccountPrivateKey().getPrivateKey())
.build();
setHttpTimeout(credential);
return credential;
}

Is Tyrus nessary to implement Java WebSocket authentication?

Although there's very similar post, it is unanswered.
My JavaFX app with WebSocket will
send user id、password to server
keep the session to let user do something like personal data management.
Learning from
Oracle WebSocket、
Tyrus 8.14 Client HTTP Authentication
I have:
#ClientEndPoint
public class loginEndPoint {
final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
public static void main(String [] args) {
AuthConfig authConfig = AuthConfig.Builder.create().disableBasicAuth().build();
Credentials credentials = new Credentials("ws_user", "password");
client.getProperties().put(ClientProperties.AUTH_CONFIG, authConfig);
client.getProperties().put(ClientProperties.CREDENTIALS, credentials);
client.connectToServer(new Endpoint() {
#Override
public void onOpen(Session session, EndpointConfig config) {
try {
session.addMessageHandler((MessageHandler.Whole<String>) (String message) -> {
System.out.println("Received message: "+message);
messageLatch.countDown();
});
//let user do some data management
} catch (IOException e) {
System.out.println("Connect Fail.");
}
}
}, cec, new URI("ws://localhost/myApp/login"));
}
}
Is these code right to do the authentication? And where could I do the server side authentication on #ServerEndPoint?
#ServerEndpoint
public class loginServerEndPoint {
}
Thanks for help.
No, it is not necessary to use Tyrus as a server implementation.
On the server-side you should secure WebSocket in exactly the same way as you secure servlet or jsp in your servlet container, which can be slightly different from container to container (mapping users to roles).
Look at authentication example
Note that this example shows up how to make authenticated WebSocket request handshake with BASIC auth scheme, but your client code disables it explicitly, so probably you want to use DIGEST scheme.

Enforcing Basic Authentication with RestEasy & TJWS

We use Resteasy to communicate between multiple backend servers & we want to lock this down so not just anyone can attach a client or browser to the restlet server.
We're using Resteasy 3.04 and as our backend services are numerous but very light-weight an embeddded TJWS webserver.
Example Server code:
public class RestEasySSLBasicAuthenticationServer {
static TJWSEmbeddedJaxrsServer webServer;
static class BasicAthenticationSecurityDomain implements SecurityDomain {
#Override
public Principal authenticate(String aUsername, String aPassword) throws SecurityException {
System.out.println("User:" + aUsername + " Password" + aPassword);
if (aPassword.equals("password") == false) {
throw new SecurityException("Access denied to user " + aUsername);
}
return null;
}
#Override
public boolean isUserInRoll(Principal aUsername, String aRole) {
// No role based checks so return true
return true;
}
}
public static void main(String[] args) throws Exception {
// Create embedded TJWS web server
webServer = new TJWSEmbeddedJaxrsServer();
// Set up SSL connections on server
webServer.setSSLPort(8081);
webServer.setSSLKeyStoreFile("K:\\source\\RestEasyTest\\server_localhost.jks");
webServer.setSSLKeyStorePass("krypton");
webServer.setSSLKeyStoreType("JKS");
// Add basic HTTP authentication to the server
webServer.setSecurityDomain( new BasicAthenticationSecurityDomain() );
// Add the restlet resource
webServer.getDeployment().getActualResourceClasses().add(PlayerResource.class);
// Start the web server
webServer.start();
// Run until user presses a key
System.out.print("Web server started. Press a key to stop...");
System.in.read();
// Stop the web server
webServer.stop();
}
}
Example client code:
public class RestEasySSLBasicAuthenticationClient {
public static void main(String[] args) throws Exception {
// Set up the keystore
System.setProperty("javax.net.ssl.keyStore", "K:\\source\\RestEasyTest\\client_localhost.jks");
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.keyStorePassword", "krypton");
// Create a new Restlet client
Client restletClient = ClientBuilder.newClient();
// *** Even WITHOUT these credentitials we can access the restlet
// restletClient.register(new BasicAuthentication("username", "password"));
// Set up the restlet request target.
WebTarget request = restletClient.target("https://localhost:8081/player/{id}");
request = request.resolveTemplate("id", Long.valueOf(1));
// Build the restlet request
Invocation invocation = request.request("application/xml").buildGet();
// Call the restlet and get returned object
Player result = invocation.invoke( Player.class );
System.out.println(result.toString());
}
}
Using the test client and a registered authentication filter works and as expected I can a 401 access error if I get the password incorrect.
However if no authentication is registered at the client then the server never calls the SecurityDomain check and access is allowed.
How do I enforce a login at the server?
You can ensure all users are authenticated by enabling security on the embedded TJWS web server.
webServer.getDeployment().setSecurityEnabled(true);

Exporting data to Google Spreadsheet from Google App Engine (Java version)

I am getting no where now. When I Google around to find a sample of "Exporting data to Google Spreadsheet from Google App Engine", I see a lot of Google Conversion API, Google Conversion API, Google Spreadsheet API and Google Docs API tutorials. But then they all deprecated from Google when I check at the Google site??? So, what is the most updated right now so I can make use of it?
=====
Okay now I use the Google Drive SDK via OAuth2 to create text file. But I have problem with this:
this is the error:
java.lang.NullPointerException at
java.net.URI$Parser.parse(URI.java:3004) at
java.net.URI.(URI.java:577) at
com.google.api.client.http.GenericUrl.(GenericUrl.java:100) at
com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:269)
at
com.google.api.services.drive.Drive$Files$Insert.executeUnparsed(Drive.java:309)
at
com.google.api.services.drive.Drive$Files$Insert.execute(Drive.java:331)
at
com.company.dashboard.service.DriveService.initDoc(DriveService.java:84)
this is the code:
private GoogleCredential buildGoogleCredential(Credential credential) {
try {
logger.warning(oauth2Service.getClientCredential().toString());
GoogleCredential googleCredential = new GoogleCredential.Builder()
.setClientSecrets(oauth2Service.getClientCredential())
.setTransport(new NetHttpTransport())
.setJsonFactory(new JacksonFactory()).build();
googleCredential.setAccessToken(credential.getAccessToken());
googleCredential.setRefreshToken(credential.getRefreshToken());
return googleCredential;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private Drive buildService(GoogleCredential credential) {
return new Drive.Builder(new NetHttpTransport(), new JacksonFactory(), credential).build();
}
public void initDoc(HttpServletRequest req)
throws Exception {
User user = UserServiceFactory.getUserService().getCurrentUser();
Credential credential = oauth2Service.getStoredCredential(
user.getUserId(),
(CredentialStore)req.getSession().getServletContext().getAttribute(OAuth2Constant.GOOG_CREDENTIAL_STORE));
if (credential != null) {
logger.warning("Using access token: " + credential.getAccessToken());
try {
GoogleCredential googleCredential = buildGoogleCredential(credential);
Drive service = buildService(googleCredential);
if (service == null) {
logger.warning("very bad!");
}
File body = new File();
body.setTitle("My document");
body.setDescription("A test document");
body.setMimeType("text/plain");
java.io.File fileContent = new java.io.File("document.txt");
FileContent mediaContent = new FileContent("text/plain", fileContent);
service.files().insert(body, mediaContent).execute();
//File file = service.files().insert(body, mediaContent).execute();
//System.out.println("File ID: " + file.getId());
} catch (HttpResponseException e) {
if (e.getStatusCode() == 401) {
logger.warning(e.getMessage());
// Credentials have been revoked.
// TODO: Redirect the user to the authorization URL.
throw new UnsupportedOperationException();
}
} catch (IOException e) {
System.out.println("An error occurred: " + e);
}
}
oauth2Service.getClientCredential() returns (xxx = client id and client secret code, not shown in here)
{"web":{"client_id":"xxx.apps.googleusercontent.com","client_secret":"xxx"}}
This is my scope:
final static List<String> SCOPES = Arrays.asList("https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/docs",
"https://www.googleapis.com/auth/drive.file");
final static String AUTH_RESOURCE_LOC = "/client_secrets.json";
final static String OATH_CALLBACK = "http://localhost:8888/oauth2callback";
This line
service.files().insert(body, mediaContent).execute();
throws NullPointerException. Any idea what had gone wrong???
P/S: Credential = com.google.api.client.auth.oauth2.Credential. I have my OAuth2 everything works good. I can retrieve user info without problem but not the Drive API. service is not null as you see I put it the log as "very bad" and it is not shown. No 401 exception is thrown means my Oauth2 is good with the scopes.
=======
DARN!!!! Finally solved the issue!!! My code was totally correct! Just I enabled the wrong API! It should be Drive API instead of Drive SDK API :/
You can generate a csv file from GAE and upload it using the Drive API with ?convert=true to have it automatically converted to a Google spreadsheet:
https://developers.google.com/drive/v2/reference/files/insert

Resources