Scenario: The application sits behind an NGINX that terminates the TLS connection and does the mutual authentication with the client. The NGINX then forwards the client certificate in an X-SSL-CERT header to the spring-based application. In the application I want to access the information provided inside the certificate and also based on this create an Authentication.
Current Approach: To get it up and running, I implemented a custom Filter that extracts the header, parses the string into an X509 certificate, extracts the required information into a custom Authentication and then uses the SecurityContextHolder to add the Authentication into the SecurityContext. This works and I can access the Authentication inside my controller methods with #AuthenticationPrinciple annotation.
However, while reading the documentation I felt that this approach might not be secure and also not as it is intended by spring since there is already an X509AuthenticationFilter to use in pre-authentication scenarios.
I then came up with the idea to just place the parsed X509Certificate inside the ServletRequest attribute and use the provided X509AuthenticationFilter. I quickly ran into issues, since I do not provide an UserDetailsService.
Questions:
Is the first approach I described considered to be valid/secure?
How can I use the X509AuthenticationFilter for pre-authentication use cases
and without providing a UserDetailsService since I don't require anything to get those information
Is it secure to directly use the SecurityContextHolder to add my custom Authentication from inside the filter
Related
There is a Spring boot app with endpoints protected with JWT. Token validation is performed by Spring boot OAuth2 Resource Server that checks tokens at Keycloak Authorization Server.
How can additional inner user validation be added to the app after it successfully passes authorization at Keycloak?
So I'd like to build some kind of a chain - if token passes validation at Auth Server then I check the username taken from JWT at local database.
Checking access-token claims against local database for access-control on a resource-server is an easy task inside authentication converters (http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(...) or http.oauth2ResourceServer().opaqueToken().authenticationConverter(...), but this is very inefficient: it is much better to have this DB access once when the token is created on authorization-server, rather than each time it is evaluated during resource-server authorization process (which happens for each request).
All the data required for access-control decisions should be included in the token already. If you need more than standard claims plus the default private claims from your authorization-server, then configure this authorization-server to add the data you need about the user when issuing access-tokens. For Keycloak, this is done with so called "OIDC protocol mappers". Those can issue DB requests, web-service calls and about anything. I have a sample of a mapper adding a private claim with a value from a web-service call in this project.
Once all the data you need is in the token, you just use it as normal in Spring security expressions of your resource-server. Here is a working sample taken from my set of tutorials:
#PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')")
In this expression, it is checked that the user either:
is greeting himself (username #PathVariable is equal to preferred_username claim in access-token)
has one of "nice" roles
has permission to greet on behalf of user with preferred_username equal to username #PathVariable (the route is /greet/{username} and this permissions delegation is taken from a private claim added by a mapper like the one in the sample linked above)
For example I need that my Web app will support two different auth methods, for GUI it will be OpenID, already configured and worked. For API it will be Http Basic Authentication based (I guess) on <basicRegistry>.
How do I need to configure web.xml that liberty will know (if it possible at all) to which authentication method redirect user?
Thank you.
See if you can make use of the authentication filters for openID. So that it will go to openID for the specified cases in filters and use default authentication otherwise. You will define a filter in server.xml and then make use of that filter in openID configuration(server.xml too).
Configuring Authentication Filters:
https://www.ibm.com/support/knowledgecenter/en/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/rwlp_auth_filter.html
You can use the authentication filter to determine whether certain HTTP servlet requests are processed by certain providers.
Liberty server authentication filter uses the filter criteria that are specified in the authFilter element in the server.xml file to determine whether certain HTTP servlet requests are processed by certain providers, such as OpenID, OpenID Connect, or SPNEGO, for authentication.
Configuring Authentication Filter for OpenId:
https://www.ibm.com/support/knowledgecenter/en/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/twlp_config_rp_openid.html
Optional: Configure the Authentication Filter.
If the providerIdentifier attribute is configured inside the openId element in the server.xml file, you can configure authFilterRef to limit the requests that should be intercepted by the OpenID provider defined by the providerIdentifier attribute.
I am learning to implement Saml, so far i have downloaded a sample of spring security with saml from this link https://github.com/spring-projects/spring-security-saml/tree/master/sample , went through the reference guide and various other SAML links.
One thing which i need to ask is, as the Service Provider has to send the Saml AuthRequest where do we define it in the program.
I have tried to implement the sample and created dummy projects to work it with OpenAM, which is working fine for SSO, but I didn't understand from where the Saml Auth Request is getting generated.
I got to know that the SP's system itself is going to generate authentication request and send it to IDP using SAML 2.0 protocol. I need help about the parameters i need to pass so that i can customize my own saml authentication request
Any Help is Highly Appreciated!. Thanks in Advance. (I know its a stupid question to ask, but couldn't help it as I am failing to get any idea.)
The authentication request is performed according to the authentication provider selected and the configuration of your filter chain. Some details of those aspects are transparent while using an high-level framework like Spring.
Spring SAML is based on the OpenSAML library, providing a set of facilities in order to easily handle the whole AuthN process for Spring applications.
Indeed, to properly complete this process, you need to setup your application endpoint (entityID), the certificates to verify the parties' identity, secure your application paths, configure the binding protocols, establish a trust relationship between an IdP and your application exchanging some metadata.
For instance, consider the code stub as follows, taken from vdenotaris/spring-boot-security-saml-sample:
#Bean
public MetadataGenerator metadataGenerator() {
MetadataGenerator metadataGenerator = new MetadataGenerator();
metadataGenerator.setEntityId("com:vdenotaris:spring:sp");
metadataGenerator.setExtendedMetadata(extendedMetadata());
metadataGenerator.setIncludeDiscoveryExtension(false);
metadataGenerator.setKeyManager(keyManager());
return metadataGenerator;
}
You can check my custom parameters for the metadata generation, customizing my application settings for the SAML-based SSO.
The AuthN request is typically performed by redirecting the user on a third-party resource (i.e. a website), where provide the credentials. After the verification, the IdP sends a SAML envelope to the requester application (Service Provider), containing user information.
I am new to spring. My requirement is:
I need to get the user name and password in my component class. validate it with by invoking the webservices available at my client.
So I want to provide security to my password which can not be directly visible anywhere.
So how to implement this?
Please give suggestions
Spring Security can participate in many different authentication environments. While we recommend people use Spring Security for authentication and not integrate with existing Container Managed Authentication, it is nevertheless supported - as is integrating with your own proprietary authentication system.
What is authentication in Spring Security?
Let's consider a standard authentication scenario that everyone is familiar with.
A user is prompted to log in with a username and password.
The system (successfully) verifies that the password is correct for the username.
The context information for that user is obtained (their list of roles and so on).
A security context is established for the user
The user proceeds, potentially to perform some operation which is potentially protected by an access control mechanism which checks the required permissions for the operation against the current security context information.
The first three items constitute the authentication process so we'll take a look at how these take place within Spring Security.
The username and password are obtained and combined into an instance of UsernamePasswordAuthenticationToken (an instance of the Authentication interface, which we saw earlier).
The token is passed to an instance of AuthenticationManager for validation.
The AuthenticationManager returns a fully populated Authentication instance on successful authentication.
The security context is established by calling SecurityContextHolder.getContext().setAuthentication(...), passing in the returned authentication object.
This could help: http://www.viddler.com/v/c596114a
I had recently been able to secure my web application and authenticate the user by using basic authentication. An added requirement was to check against user's ip address from request parameter and I leveraged use of Custom authentication details source and override of BASIC_AUTH_FILTER. (see:http://stackoverflow.com/questions/9854592/accessing-httpservletrequest-during-daoauthenticationprovider-authenticate-in-sp)
Now I have a Spring Web Service that uses SimplePasswordValidationCallbackHandler and the same AuthenticationManager / Provider configuration as above (except for the http namespace configuration which has all my custom filter logic).
I would like to do a similar activity to authenticate a user completely only if their ip addresses match when authenticating in a Web Service.
I pass the username and password in the SOAP headers and authentication happens without any issues.
Any thoughts if i can reuse my existing configuration here for the AuthenticationDetailsSource and Custom filter. Is this even achievable or am I on a completely different track here?
Thanks.
I added a RequestContext Listener to my web.xml and got access to the HttpServletRequest using a RequestContextHolder during my authentication process in a custom DAOProvider.
Anyone with a better solution, let me know !