Client certificate authentication in spring security - spring-security

I need to configure 'Client certificate authentication' in Glassfish 3. I tried many scenarios but couldn't configure. The requirement is - the user who imported the .cer file can alone access the application.
So we need to configure in such a way that we need to validate the .cer file that is uploaded into the browser (through which the client is trying to access the application).
Once the certificate file is validated, then we need to show the login screen (form-login). Further we validate the username/password of the user.
I tried several configuratiosn (in applicationCOntext-security.xml file) but in vain.
Can anyone tell how to configure spring security so that both the client certicate authentication (done first) and then the form-login (done next)?

Spring does not do SSL its Glassfish that is setting up the SSL connection. By the time the request has arrived in Spring security all spring security knows is that the request came in over a secure channel but does not know how the secure channel was configured.
To setup client certificate authentication you need to configure glassfish to require a client side certificate to setup the SSL connection and to refuse the connection if the client does not provide a valid certificate.
This way you will get the behavior you want if the client does not present a valid certificate to glassfish glassfish never routes the call to spring.
I do know how to setup client side ssl authentication with glass fish so I can't help you with exact details, but google should know the answer.

Related

Getting client certificates in Azure Web App using OWIN

If you are using Azure Web Apps to host your web application (let it be an ASP.NET MVC web app) you do not have the possibility to set up the IIS behind the Azure Web App to accept client certificates through an HTTPS connection. My application has some Web API endpoints that would be only accessible if the user has the correct certificate with the allowed thumbprint. However, I have other endpoints as well (and of course the website) that would be accessible without a client certificate. So in my case the only way is to accept client certificates.
I am not sure about that, but if I know well I can still get the client certificate by using OWIN while the SSL Settings in IIS is set to Ignore. If I use OWIN and go through the OWIN environment I can see a key called ssl.LoadClientCertAsync.
I am implementing endpoints that a third-party service will call, so I have no control over the content of the request. I know that there is a ssl.ClientCertificate key, with type X509Certificate, but in my case this key doesn't exist.
I have found some C# solution about using this ssl.LoadClientCertAsync key to get the certificate like in the CheckClientCertificate method of Katana or the solution in this C# Corner article. In every solution that I can find in the net, the author gets this type as a Func<Task> and then calls this task, by for example using the await operator.
var certLoader = context.Get<Func<Task>>("ssl.LoadClientCertAsync");
if (certLoader != null)
{
await certLoader();
...
After that they retrieves the certificate by using the ssl.ClientCertificate key.
var asyncCert = context.Get<X509Certificate>("ssl.ClientCertificate");
In this example, my asyncCert variable is always null. There weren't any ssl.ClientCertificate key in the OWIN context. I have tried to use the X509Certificate2 instead of X509Certificate, but I still got null.
My question is is it possible to get the client certificate in an Azure Web Site while the default SSL setting is Ignore by using OWIN? If yes, why can't I get the certificate using the ssl.LoadClientCertAsync key?
According to your description, I have created my ASP.NET MVC web application for working with client certificate in OWIN to check this issue. The following code could work on my local side:
if (Request.GetOwinContext().Environment.Keys.Contains(_owinClientCertKey))
{
X509Certificate2 clientCert = Request.GetOwinContext().Get<X509Certificate2>(_owinClientCertKey);
return Json(new { Thumbprint = clientCert.Thumbprint, Issuer = clientCert.Issuer }, JsonRequestBehavior.AllowGet);
}
else
return Content("There's no client certificate attached to the request.");
For SSL Settings set to Accept, I could select a certificate or cancel the popup window for selecting a certificate.
AFAIK, we could enable the client certificate authentication by setting clientCertEnabled to true and this setting is equivalent to SSL Settings Require option in IIS.
As How To Configure TLS Mutual Authentication for Web App states about accessing the Client Certificate From Your Web App:
If you are using ASP.NET and configure your app to use client certificate authentication, the certificate will be available through the HttpRequest.ClientCertificate property. For other application stacks, the client cert will be available in your app through a base64 encoded value in the X-ARR-ClientCert request header.
My question is is it possible to get the client certificate in an Azure Web Site while the default SSL setting is Ignore by using OWIN?
AFAIK, the current SSL Settings for client certificates only supports Ignore and Require for now. When hosting your web application on azure web app, for the client users who access your azure web app with client certificate authentication, they could specify the certificate to a base64 encoded value as your custom request header when sending request to your azure web app, then your could try to retrieve the header and verify the cert if the cert custom request header exists. Details, you could follow this sample.
Additionally, you could use Azure VM or Azure Cloud Service instead of azure web app, at this point you could fully control the SSL Settings in IIS.

How to validate new SAML certificate

I'm working on an app that acts as a SAML service provider. It's written in Rails and uses the omniauth-saml and ruby-saml gems.
Our certificate is about to expire, and we need to create a new one. I'm tasked with verifying that the new one is working. However, none of the IdPs that I've tested with seem to care which certificate I use. When I set them up with the old cert and then switch our app to using the new one they all allow SP-initiated login as if nothing changed.
The app needs to work with all IdPs, and I think that some of them do validate assertion signatures. I need to find an IdP that fails to accept an SP-initiated login assertion when the signature does not match the one that was set up. I've tried Okta, Jumpcloud, and Ping without any luck.
One question is: why don't these IdPs care about the signature for SP-initiated login. But the main question is: how do I find one that does care so that I can test the new cert?
Thanks!
There are two places where your SP's certificate is used: (1) the SP can digitally sign its authentication request to the IdP, and (2) the IdP can encrypt parts of its response with your SP's public key.
For situation (1), if your SP is signing its requests with the new certificate but the IdP responds as before, it could very well be that the IdP is simply ignoring the signature. The IdP might have to be configured to expect and require signed requests before it will fail on an unknown certificate. But note that it is up to the IdP whether it will verify signed requests; for example, according to this post Okta does not verify the signature of signed authentication requests.
For situation (2) use Firefox's SAML tracer or something similar to verify that part of the response from the IdP is encrypted. If not, that would explain why switching to a new certificate that the IdP does not know about continues to work.
It may also be that your SP needs only to know that the person authenticated successfully against the IdP and nothing else, in which case, your SP's certificate is superfluous.
In particular, the Shibboleth IdP can be configured to send back encrypted assertions.
For me, by far the easiest to use and configure IdP or SP test connectors can be found here: https://support.onelogin.com/hc/en-us/articles/202673944-How-to-Use-the-OneLogin-SAML-Test-Connector
There is a list of test connectors that will help you to test different kinds of connections.

WebSphere Liberty Profile OIDC Client URL

I am trying to use the WebSphere Liberty Profile OIDC Client feature. I have the feature installed and configured, but I am confused about what URL I should be using to connect to it. In the WLP Knowledge Center, it shows an example like this:
https://server.example.com:443/oidc/endpoint/PROVIDER_NAME/authorize
But when my WLP server comes up, I see the following URL in the log:
com.ibm.ws.webcontainer.osgi.DynamicVirtualHost I addWebApplication SRVE0250I: Web Module OpenID Connect Client Redirect Servlet has been bound to default_host.
com.ibm.ws.http.internal.VirtualHostImpl A CWWKT0016I: Web application available (default_host): http://ibm669-r9v0dvb:11080/oidcclient/
I don't know whether to use 'oidcclient' (probably) or 'oidc'. I also don't know what to put as the PROVIDER_NAME. I tried using the ID of my OIDCClient:
<openidConnectClient id="oidcRP"
clientId="${oauth.client.id}"
clientSecret="${oauth.client.secret}"
authorizationEndpointUrl="${oauth.authorize.endpoint}"
tokenEndpointUrl="${oauth.token.endpoint}"
httpsRequired="false"
redirectToRPHostAndPort="https://myhost.com:443">
I tried connecting with this, but it's not finding it:
http://ibm669-r9v0dvb:11080/oidcclient/endpoint/oidcRP/authorize?scope=openid&response_type=code&client_id=XXX&redirect_uri=https://myhost.com:443
com.ibm.ws.webcontainer.extension.DefaultExtensionProcessor W handleRequest SRVE0190E: File not found: /endpoint/oidcRP/authorize
Can anyone tell me what URL I should be using to connect to the client?
The Liberty openidConnectClient feature enables Liberty as a client to openid connect provider. The configuration parameters inside openidConnectClient are information about openidConnectProvider, for example, the openidConnect provider's authorization endpoint and token endpoint.
What is your openid connect provider? Liberty also can be configured as openid Connect provider. If you also want to use Liberty as openid connect provider, you can create another Liberty instance and enable openidConnectProvider feature.

IIS Passing client certificate to rails

I have an application written in Rails that must be ran behind a IIS server due to restrictions by the client, the government. We have to have SSL authentication. So what I can't figure out in my hours of searching Google is how to get IIS to pass the client certificate to the rails server (thin).
I've seen tutorials on Apache that use:
SSLOptions +ExportCertData
Which then make it available to the request object. Any ideas on how to configure IIS to do the same?
At least in the way that you ask the question IIS cannot provide a client certificate as the client cert would be issued by a third party. So you need to get the x509 cert that your application and then the cert is authenticated as part of the initial connection request with iis.
As to the apache function to provide the ssl cert from the server to the client, this functionality is not exposed by iis.
That's why you were not able to find anything on google
The main reason companies want to run Rails(or Other) applications behind an IIS server is for SSO apart from protecting the resources.
See if this helps.
We have been running our Rails app behind IIS at quite a few customer locations. We run our Rails app in JRuby inside Tomcat.
The steps to install the JK ISAPI redirector plugin are here
http://tomcat.apache.org/connectors-doc/webserver_howto/iis.html
All Rails contexts are protected in IIS using standard IIS authentication schemes, Integrated Windows Authentication ( Negotiate, NTLM).
Within the Rails app one can get the logged in user's information.
request.env['java.servlet_request'].get_remote_user
The Rails app also connects to Microsoft AD for additional user information like email, department etc.,
Since the Rails is blindly trusting the IIS server for authenticaiton it needs to be prevented from direct access.
1. Disable HTTP ports in Tomcat
2. Enable only the AJP port
3. Add an IP restriction so that it accepts connection only from the IIS server(s)
==
I do not think it is possible for IIS to pass on the certificate details. We tried to extract the Kerboros tokens ( for kerboros authentication delegation ) without much success and realized it is not possible.
After being told this may be impossible. I've finally figured it out! Here are the steps that I took.
Using OpenSSL create your own CA certificate.
Using the generated CA certficate create and sign other certificates with Open SSL.
Open Internet Information Service Manager click on the server, then click on server certificates.
Click Import under the Actions column
After importing click on your site.
In the Actions column click bindings...
Click add, scroll to https, and select the CA certificate that you imported
Click on your site again to get to the menu and click on SSL settings
Check require SSL and then click the radio buttion, require
Click your site again then click on the configuration editor (installed in IIS 7.5 can add-in in 7.0)
Go to system.webServer/security/authentication/iisClientCertificateMappingAuthentication
Set enabled to true
Set manyToOneCertificateMappings to true
Click on the ... box on the far right-end of manyToOneMappings
Click add under actions column, under collections
Add the username and password of the user you created (can be on local machine)
Now, go to the main server and restart.
You should be able to see the certificate using request.headers hash.
Variables for the hash include:
CERT_SERIALNUMBER
CERT_SUBJECT
CERT_ISSUER
HTTPS_SERVER_ISSUER
HTTPS_SERVER_SUBJECT
If you cannot find something you may have to install a module (for like authentication). I don't remember which ones I installed.

jasig asp.net mvc cas client page is not redirecting properly

I have been using jasig .net cas client. I have setup cas server on my local computer which can be assessed using https://localhost:8443/cas-server-webapp-3.4.12/login
I have set authorize attribute on Account controllers logon action.
i am following everything given in this url https://wiki.jasig.org/pages/viewpage.action?pageId=32210981
when i run the application, it does go to cas login page but after authentication it returns with http://localhost:1672/ and then in browser it gives error as "The page isn't redirecting properly".
i don't know how i am getting this error, everything is setup properly in web.config.
Please help
when i use http://localhost:8080/cas-server-webapp-3.4.12/login (non secure url) instead of https://localhost:8443/cas-server-webapp-3.4.12/login(secure url) it works.
I think i have a problem with self signed certificate. Is it possible to create valid certificate and use it. At least i should try creating a valid certificate and try. But i don't know how to create valid certificate. Please also tell me how to create valid certificate. I tried google but not successful to find how to create valid certificate so that browser doesn't display "self signed certificate error".
For my own experience, other than getting the self-signed cert to work:
I have to install the self-signed cert from the SSO server to my Windows 2008 Server hosting the webapp).
Install the certificate under Trusted Root Cert Authorities on BOTH the user account and the machine account.
You can do this under MMC and then Add the certificate Snap-in.
Test your setup using IE to browse to the sso server in question.You should not see anymore warnings about the cert. Remember use IE to check, other browser does not seem to care about the Trusted Root Cert setup.
Next, when deployed the ASP MVC, I have to use classic Application Pool and
for my cas config setup in web.config leave both the proxyTicketManager and the gatewayStatusCookieName as empty string.
I am connecting directly to the sso server so these two be taken out, or else protocol error and infinite loop.
Then no more infinite redirect loops complains.
I found what the problem was. When we are using secure connection we need to have SSL certificate on both side, at CAS server side and at our webapplication side.
so at CAS server side it has to be
https://localhost:8443/cas-server-webapp-3.4.12/login
and at our web application side it has to be
https://servername/mywebapp
If you are using a self-signed certificate be sure that the server running CAS trusts the certificate of the web application.
you should specify the return url after success login in the web.config (just the server not the entire url)
example: you app is on http://localhost:8080/someWebApp/
when you go to the login page, you can see on the query string parameter the return url encoded
<casClientConfig casServerLoginUrl="https://localhost:8443/cas-server-webapp-3.4.12/login"
casServerUrlPrefix="https://localhost:8443/cas-server-webapp-3.4.12/"
serverName="http://localhost:8080"
notAuthorizedUrl="~/notAuthorized.html"
cookiesRequiredUrl="~/CookiesRequired.html"
redirectAfterValidation="true"
renew="false"
singleSignOut="true"
ticketValidatorName="Cas20"
serviceTicketManager="CacheServiceTicketManager"/>

Resources