How do I get the current user from within an AWS AppStream? - java

I'm prototyping deployment of an application via AWS AppStream. Access to the stream is managed via a web portal (using SAML). My application needs to know the identity of the user. I could prompt them but I don't want to make them login to both the portal and the application. I want to get the credentials they supplied at the portal. (AppStream instances run under the "PhotonUser" account, so I can't get the username from the OS.)
The AWS SDK has a Session class which contains the user ID but I can't find a way to get an instance of it for the current streaming session.

Have the portal pass a token identifying the user into the AppStream as session context. The token can be anything you want (subject to an unenforced 1024 byte limit) but should probably include a timestamp so that it can be expired and a signature to ensure that it hasn't been forged or tampered with.
Modify your portal to create a custom URL for each user via the CreateStreamingURL API to supply the token as session context. The application in your AppStream will see the session context a command-line argument. Parse and validate the token (i.e. check it for expiration and verify the signature).

AppStream_UserName environment variable is set in each and every session.
So your portal should grab their email address and use this with CreateStreamingURLRequest(plus stack, fleet etc). The portal should now redirect their browser session to this URL.
In that running instance AppStream_UserName will be their email address.

Related

Implement Single Sign On (SSO) using offline cookie in Keycloak

Can we implement Single Sign On (SSO) using offline cookie in Keycloak ?
I have application 'A ' connected to Keycloak 7.0.1 (KC) server for authentication. KC generates the active session and offline session for user under 'clientA' and returns access token & offline token to user. Offline token has validity of say X days. So when user tries connecting to application 'A" again it uses offline cookie to get the access token and user gets authenticated. So authentication is working using that offline cookie for Application 'A'.
Now I have another application 'B' , lets say it is hosted on same or different domain. KC is able to access the same offline cookie but it doesn't allow the authentication. The client for this application is 'client B'. The error which I get is "Session doesn’t have required client"
Looking at error and reading at articles I understood that two different clients cannot access same offline cookie. But still I wanted to know do anyone came across this scenario and what was the way used to allow both the applications to use same offline cookie or does we have any keycloak configuration which is missing .
Editing this question:
Can we have any REALM level Offline Token instead of creating different offline tokens for each client in realm ?
The keycloak is there to generate the credentials for the different applications, you need to create a second client in the same realm for the application b (you say you have already done that).
I do not think that you can use the access token from application a to application b. Maybe you could do that depending in the way that you generate the token if the two applications share the same private key, but if you do that then probably you do not need keycloak.
Then make an authorization request in this client, since you already have a session in keycloak this should happen automatically and generate the credentials that you need for application b.
To see if this works correctly, I would try to login directly in application b, go to keycloak, login there and see if the token provided can log me in application b.
Sorry for the high level response, but your question is also quite high level itself.

Validate a user requests between servers

Background: I am creating a file server. I am using Tomcat behind Nginx reverse proxy. I have a main server which host the UI and lots of edge servers where I hope to store user uploaded files and serve them back. It's a private file storage so only the file uploader should be able to download their uploaded files.
Problem: I authenticate users on the main server when they login to their account by creating a session and keep it to validate further requests from users (regular stuff). This information is not propergated to edge servers, edge servers serve files to any request. That's not what I want. I want to authorize downloads only to file owner.
Now, here I am trying to avoid Tomcat clustering where edges and main servers configure as a cluster that has sessions distributed. Site is SSL supported. Is there a way to validate a user's login status when a file download request reach an edge server from a user who is already logged in(created a session) the main server?
I see several approaches you could use
You can use a form of "claim based authentication" or resource access token.
Claim based authentication - you could use e.g. a JWT token, which should contain some necessary information (user id, account id, authorization, expiration, ..) and is signed by a shared secret (between the main server and file servers) or by a private key from the main server.
Advantage is, that the edge server can validate the token based on the hash or signature without contacting the main server. Disadvantage is, that there must be logic to decide whether the user has access to the requested resource.
see: https://jwt.io/
Resource access token - this approach that is used some cloud storage providers (AWS S3, IBM Object Storage, ...) - the main site will return a resource URL with some extra parameters - e.g. account, nonce, expiration, signature. The resource (edge) server must check the expiration and signature and provide or deny the resource
Advantage is, that the edge server doesn't care about any authentication and the authentication and authorization is completely in scope of the main server. Disadvantage is, that the provided resource URL must have limited expiration time.
see: http://s3-expiry.50projects.com/
Note:
placing the condition that the resource server may not communicate with the main server effectively you're unable to check if the user is logged in, except using SAML SSO with SLO (single logout) or OIDC with session management

Java web application - retrieving client windows credential

I have a java web application(hosted in Linux) which speaks to a document management system which is a .NET based system via rest services. By default SSO Kerberos authentication is used in document system and for the same we are passing SSO Token to identify the user who accesses our application via web browser. This works fine and the document system is able to identify the user and allows user to upload document.
However we have a problem when a user who belongs to a different domain/AD tries to access the application. This is due to the external trust level between the environment document service is hosted and user environment. The document mgmt system supports NTLM authentication to handle this scenario and we were told that we need to pass credential object in the request. It appears there are easy ways for .NET client to extract user credential using CredentialCache object but I am struggling to find equivalent in Java.
I am trying to find out a way to pull the users windows credential so that I can set in the credentials object before i send the request to document system. Our application is SSO enabled, hence we dont want the user to explicitly pass his windows credential.

SSO - CAS Protocol - renew parameter

I had a (maybe simple) question about the CAS protocol.
From what I read in the protocol description, using the renew parameter in the /serviceValidate call force the user to provide its crendential again.
2.5.1. parameters
The following HTTP request parameters MAY be specified to /serviceValidate. They are case sensitive and MUST all be handled by /serviceValidate.
[...]
renew [OPTIONAL] - if this parameter is set, ticket validation will only succeed if the service ticket was issued from the presentation of the user's primary credentials. It will fail if the ticket was issued from a single sign-on session.
Since each ticket is specific to a given service, does that mean that the renew parameter force the user to provide its credentials each time he attempt to access the application, even if he already logged in and used other applications ?
Setting "renew=true" on a /serviceValidate URI indicates that a service ticket request will only be validated by CAS if the user obtained that ticket through presenting primary credentials (user id, psw). So, if you are attempting to validate a service ticket when you have already established an SSO sessionin a prior attempt, setting "renew=true" to true will cause the validation to fail.
However, if you are attempting to force the user to enter his credentials every time using the /login URI call to the CAS server, then "renew=true" would be the parameter to use. In other words, if application X is specified as a service URL to the /login URL and renew is set to true, users will be forced to provide credentials regardless of whether or not a previous SSO session exists.
Hope that helps. :)

Restrict single session for a user in google account

Is it possible to force google to create only one session for a single user?
I have created services in GAE, that uses google id to authenticate users.
Now a single user creating multiple sessions from multiple PCs by sharing
his username/password. I want to restrict this.
In simple language after successful login the application should sign out all other
session for this user.
In gmail there is a link at the bottom of the page by the name last activity details.
On clicking details it shows current sessions and also give option to log out other
session. I want same functionality programmatically.
There is one more option: before logging in detect whether the user is already logged
on?
Have a look at this
http://mail.google.com/support/bin/answer.py?ctx=%67mail&answer=45938
see Concurrent sessions
If this information can be accessed somehow I can take appropriate action.
It's certainly possible.
If you're using Google Accounts for authentication, a user logs in by posting their credentials to Google, and Google returns an authentication token to your site which is then stored as a cookie in the user's browser. The token is good until the cookie expires (24 hours by default) or until the user logs out.
If you want to track multiple login sessions, you can write handlers designed to run after login or logout. If your normal post-login return URL is "/do_stuff", you might change this to "/finish_login?next=%2Fdo_stuff". In that handler you could create an entity in the datastore representing the session, with a reference to the Google Account, the IP address that logged in, and the login timestamp (current timestamp). You can write the session entity key to another cookie in the user's browser. After you're done, redirect to the "next" URL.
After logout you can have a similar handler that checks for the session entity key cookie, deletes the entity, and deletes the cookie.
If you want to show the user that they are logged in from multiple locations, query for session entities associated with their Google Account that are less than 24 hours old (or whatever your cookie expiration is set to).
If you want to remotely log out another session, you might need to write your own version of the login_required decorator that Google offers in webapp.util. Your version would need to verify that the user is logged in, verify that sent a session key cookie, and verify that the associated entity still exists and is owned by the correct account.
There is nothing that prevents you from storing login details in Google App Engine Data service.
As a consequence, you can store all login details for a user in its associated object. As a consequence, I would say there is no difference between GAE and a traditionnal web application - excepted that you'll store login infos in database, instead of letting your web front-end handle it.

Categories

Resources