How to implement a Certificate-based JAAS LoginModule - portability

To authenticate a user, a JAAS LoginModule ask its environment about the user's data and credentials by passing appropriate Callback's to its enclosing CallbackHandler. The same mechanism is also used for user interaction.
If the only information that the LoginModule needs to do its authentication are username and password there is no problem: one uses the standard Callback types javax.security.auth.callback.NameCallback and javax.security.auth.callback.PasswordCallback. But apparently there is no such standard for retrieving an X509 certificate.
So how does a LoginModule asks its environment about X509 certificates? I know that there are application-server-specific Callback types for this, but I am looking for a portable solution if there are any.

Related

Encrypting and decrypting data with a key generated through crypto/pbkdf2 in Golang

I'm trying to encrypt my sensitive data for an application. For the key generation part, I'm using crypto/pbkdf2. I'm generating the encryption key on the fly based on the user supplied password. When a user is created, that's when I'm encrypting the corresponding data of the user with the user's supplied password. However, whenever that particular user tries to access a resource, I've to decrypt the data before showing it to the user. Where do I get the password from, everytime an endpoint is called by that user to access a resource?
Note: I'm storing the hashed password of the user in the database schema, also I don't want to store the encryption password anywhere!
The typical solution to this is called token-based authentication (or in OAuth terms, Resource Owner Password Credential Flow).
Create a "login" endpoint that will derive the encryption key from the supplied username/password and exchange it for a (time-limited) "access token", storing it in a key-value store with TTL support (e.g. etcd, Redis).
Then each subsequent request will need to supply the access token (e.g. in the Authorization header), which is then used to retrieve the encryption key from the key-value store.

How do I ensure a SAML Assertion's Identity Provider with an embedded X509 Certificate is Legitimate?

I am trying to implement a SAML Service Provider in order to allow for SSO to a cloud-based application, this application can host multiple tenants or companies. Normally, the user enters an e-mail address (which acts as their User ID) and their password to log in (the tenant would be identified by a URL parameter).
The SAML assertion that is received has the X509 certificate embedded in the payload, which is used to validate the signature of the SAML. While the signature can be used to verify that the assertion is valid, there is concern that someone other than the Identity Provider can generate their own public/private keys, sign their own assertion with a correctly "guessed" valid tenant ID and user e-mail address, then potentially gain access to the application.
What is a mechanism or technique used to identify that an assertion and its embedded certificate came from a specific identity provider other than the information contained inside the SAML payload? While I have read that certificates could be downloaded from identity providers, there is concern that those certificates would expire or become revoked, and additionally, we would also have to store them on our side. There is a legitimate concern that these scenarios would cause downtime for users.
One other small question, as we require a tenant ID to determine which tenant is signing on a particular user account, is it common (or proper) to provide that identifier through the URI, such as in the URL path or as a parameter on our endpoint receiving the SAML assertion?
SAML Trust
When you implement your SAML SP, you will be asked to pre-configure the signing certificate of your target SAML IdP. Therefore, your SP will only trust any incoming assertions signed with that particular signing certificate.
SAML Configuration
Configuration of a SAML SP can be done by setting up all IdP parameters including signing certificate manually, or by specifying a metadata file which contains all IdP parameters, including the signing certificate.
You may download the metadata file from IdP and use it locally in your SAML SP, or specify the URL of the metadata file and let your SAML SP to download and use it.
You may refer to Azure AD's SAML metadata URL as an example:
https://nexus.microsoftonline-p.com/federationmetadata/saml20/federationmetadata.xml
Obviously, this URL should be TLS/SSL protected and its content should only be modified by the IdP.
SAML Signing Certificate Rotation
When a signing certificate is rotated, the trust between IdP and SP is lost. You will need to re-configure your SP to trust the new certificate directly or refreshing the metadata file.
If you choose to configure your SAML SP by specifying an IdP metadata URL, you may consider configuring your SAML SP library to download and refresh the metadata regularly from IdP.
In this way, your SAML SP will have a trusted way to validate the latest signing certificate even though the certificate might be changed.

HTTP-Post binding with isPassive

My question is very similar to: How should I be implementing the HTTP POST Protocol Binding for SAML WebSSO Profile?
But I couldn't find a proper answer in it. Is it possible to send a request via an HTTP-Post binding with isPassive set to true. The Oasis specifications say that the IdP must not "visibly" take control of the user interface. Thus the IdP must be aware of the user somehow.
If the user is already active on a session on the SP side, how do I relay that information to the IdP and have them re-authenticate the user?
I want to verify the user, without hindering the user's flow...
There are a few common ways to re-authenticate a user with IsPassive=true. For example, Integrated Windows Auth (Kerberos) and x509 Cert Based Auth can both be done w/out visibly working with the user's experience.
If you combine a ForceAuthn=true and IsPassive=true in your AuthnRequest, it should force the IDP to re-authenticate the user if both conditions can be met.

Spring security - Is username and password must for creating authentication

I am using spring security to authenticate a user. The user is authenticated by a third party and will already be authenticated when he reaches my application.
To implemented this, I have simulated a Authentication object.
I don't have any username and password and instead just have identifier. I check if this identifier is valid or not using my custom code.
My query is as follows:
Do I require a username and password to create a authentication object.
I have done without providing username and password and my application works fine.
I just want to ensure that I am using spring-security correctly.
Is there any impact of not putting username and password in Authentication object. I read below in AbstractUserDetailsAuthenticationProvider:
// Ensure we return the original credentials the user supplied,
// so subsequent attempts are successful even with encoded passwords.
I have also implemented a custom provider.
What does above comments means?
Is my approach correct?
The Authentication interface in Spring Security represents a token for carrying out validations against the configured security rules and the current call context. This interface has six methods of interest - getPrincipal, getCredentials, getDetails, getAuthorities, isAuthenticated and setAuthenticated.
Since you are authenticating users on your own, you should be mostly concerned with calling setAuthenticated(true) at an appropriate stage in the flow so that isAuthenticated starts returning true to indicate an authenticated user. Additionally, you may add GrantedAuthoritys to the Authentication for any role-based checks to work correctly.
However, it will be useful to make sure that getPrincipal (username in the case of form login) returns a unique value per user or per session. This will prevent the possibility of user sessions getting interchanged due to non-unique principal, which is used by the framework to identify users uniquely.
You may leave getCredentials and getDetails unimplemented. In fact, getCredentials (password in the case of form login) should be left unimplemented in your case because your application does not have the credentials used to actually authenticate the user; plus, it is a security risk to keep the credentials around after the user has been authenticated successfully.

Accessing Credentials on TAM Backend Server

I have a setup with Tivoli Access Manager (TAM) as reverse proxy for some application servers on the backend side. TAM is responsible for authenticating users. Is it possible to access the credentials a user passed in during TAM authentication in the backend applications?
I need this because the backend applications connect to a Host-System and there the credentials are needed to log in.
there are a couple of options you might have for this :
Since you mention TAM, I guess you are still using 6.X, so you can use a custom CDAS (Cross-domain Authentication Service) library. You would need to implement the library yourself in C and handle the authentication part and return the clear text password as an extended entitlement in the credential. This will allow you to add this extended entitlement as an injected HTTP header for the junctions that require the password. You can get more information here : http://www-01.ibm.com/support/knowledgecenter/SSPREK_6.1.0/com.ibm.itame.doc_6.1/am61_web_devref58.htm%23chap-wsd-write-custom
You can implement your own External Authentication Interface. EAIs are external web applications where WebSEAL can delegate the authentication part. In that EAI, as in CDAS, you would have to handle the authentication part yourself - probably against TAM user registry - and then return the clear text password as an extended attribute in the credential to be used as a custom HTTP header for the junction that requires it. See http://www-01.ibm.com/support/knowledgecenter/SSPREK_6.1.0/com.ibm.itame.doc_6.1/am61_web_devref128.htm%23appx-wsd-eai
Leverage Tivoli Federated Identity Manager and a custom STS chain to do the authentication and return the clear text password as part of the credential.
For all 3 of the above options, you would need to modify the existing backend application to read the injected HTTP header and use the clear text password to perform the actions to the Host.
I have done all 3 for various integrations and I think your best choice is writing an EAI, as CDAS got deprecated with ISAM 7 and the 3rd option requires an additional software component.

Resources