How do I silently request a specific SSL client certificate - asp.net

I have an ASP.NET MVC5 site that uses forms authentication, but is also using client certificates for an added layer of security by setting:
<security>
<access sslFlags="SslNegotiateCert" />
</security>
The client certificate is optional because it isn't required until the user actually attempts to log into the site. When the user attempts to log in, the site will validate the Thumbnail, Issuer, and compare the Subject to the user attempting to log in (there will be a different certificate per user).The problem is that every time a user comes to the site they are prompted to provide a client certificate when they first enter the site, which may cause issues if:
they accidentally select the wrong certificate
want to log off & log back in with a different user (not re-prompted for a cert)
Is there a way to silently\automatically detect a client certificate based on the log-in provided rather than having the user select a certificate on first entering the site?
EDIT: Adding more specific example of Actual\Desired behavior
Actual Behavior:
User opens up Chrome and goes to http://www.example.com
Chrome pop-up asks user what client certificate they want to use
User chooses "user3 (www.example.com)"
User sees unauthenticated home page view & clicks the "Log In" button
User enters Username: "user2" and Password: "****"
Site validates that ClientCertificate.Subject == Username (fails because certificate is for "user3")
Desired Behavior:
User opens up Chrome and goes to http://www.example.com
User sees unauthenticated home page view & clicks the "Log In" button
User enters Username: "user2" and Password: "****"
Browser does something to silently detect if client has certificate "user2 (www.example.com)" with little to no user interaction
Question: Is the "Desired Behavior" possible in some way? (header? javascript? browser plug-in?)

By default, and due to security issues, there is no way to select a certificate for the user at all when he is visiting a website.
The user can configure their browser to use a specific certificate for a website by default if he wants, but that's a different thing.
For the second part, the certificate is used to secure the connection between the browser (client) and the server, so if you want to use another certificate you should entirely finish the connection between the browser and the server, unfortunately you would need to close the browser and open it again for that to happen in most cases. Or by cleaning the certificate cache, but that needs to be done manually by the user in his browser.
You can find a very good explanation about how certificates and SSL works here:
https://security.stackexchange.com/questions/20803/how-does-ssl-work

I am not aware of a way to do this within a single application. One way to do it is to create two asp.net-mvc applications. The second site would be a sub-directory application with the SslNegotiateCert in the sub-directory's web.config and contain all the secure methods/logins etc.

Related

GoLang: Prevent browser cache pages when clicking "Back" button

I've recently started developing e-commerce app with multiple types of users, and currently I am experiencing some issues with browsers Page Cache. Here is one example for user authentication
Authentication Token is generated
Authentication Token is written into the database
Authentication Token and its expiry is saved into the user session
I wrote middleware that checks if user is authenticated and if its authorized (checks the token and access level) as well as expiry - tested it, it works. On "Log Out" I am destroying a session and renewing the token with Session.Destroy(r.Context()) and Session.RenewToken(r.Context())
Here is the problem:
I log in as "Admin" and go to DASHBOARD page for which only admin users are authorized to access.
I logout
I login as regular user and click "BACK' on browser it takes me to Dashboard page when it should not. But, when I refresh the page it does say "UNAUTHORIZED" which is what I was expecting when clicking "back" or something.
I was searching through the internet and found a "solution" where I set the headers in the following manner:
w.Header().Set("Cache-Control", "no-cache, private, max-age=0")
w.Header().Set("Expires", time.Unix(0, 0).Format(http.TimeFormat))
w.Header().Set("Pragma", "no-cache")
w.Header().Set("X-Accel-Expires", "0")
This however, does not work for me. I do see these headers in the NETWORK card when I open my Web Developer Tools, but problem remains.
What am I doing wrong?

Firebase Auth - customized redirect domain prompts NET::ERR_CERT_COMMON_NAME_INVALID warning

I'm using Firebase Authentication for my web app, and customizing the redirect domain for Firebase Authentication's Google Sign-In feature so that Google's authentication page will
show Continue to: https://auth.mydomain.com,
instead of Continue to: https://my-app-12345.firebaseapp.com.
So I did four steps according to instructions on Firebase's documentation:
(1) Create a CNAME record for auth.mydomain.com that points to my-app-12345.firebaseapp.com
(2) Add auth.mydomain.com to the list of authorized domains in the Firebase console
(3) In the Google OAuth setup page, whitelist the URL of the redirect page which is https://auth.mydomain.com/__/auth/handler
(4) Edit my app's JavaScript code which initializes Firebase library:
var config = {
...
// from 'authDomain: my-app-12345.firebaseapp.com,'
authDomain: 'auth.mydomain.com',
...
};
After that, however, when my app invokes firebase.auth().signInWithRedirect(provider) method, web browser will show privacy warning like the following:
Your connection is not private
Attackers might be trying to steal your information from auth.mydomain.com (for example, passwords, messages, or credit cards). Learn more
NET::ERR_CERT_COMMON_NAME_INVALID
...
This server could not prove that it is auth.mydomain.com; its security certificate is from firebaseapp.com. This may be caused by a misconfiguration or an attacker intercepting your connection.
Proceed to auth.mydomain.com (unsafe)
And certificate information is as follows:
firebaseapp.com
Issued by: Google Internet Authority G3
Expires: Tuesday, 13 November 2018
This certificate is valid.
Details
Subject Name
Country: US
State/Province: California
Locality: Mountain View
Organization: Google Inc
Common Name: firebaseapp.com
And below is URI:
https://auth.mydomain.com/__/auth/handler?apiKey=apiKey&appName=%5BDEFAULT%5D&authType=signInViaRedirect&providerId=google.com&scopes=profile&redirectUrl=https%3A%2F%2Fwww.mydomain.com%2Flogin&v=5.0.4
Why does customizing the redirect domain for Google Sign-In prompt NET::ERR_CERT_COMMON_NAME_INVALID warning, and how should I do to avoid the warning message from prompting, e.g. adding Subject Alternative Names into the certificate, using auth.mydomain.com's own certificate?
By the way, in the above warning page, if Proceed to auth.mydomain.com (unsafe) is clicked, authentication will work as expected.
Because auth.mydomain.com points to my-app-12345.firebaseapp.com via CNAME record, host of firebaseapp.com should provision SSL certificate for auth.mydomain.com. It has to be done in Firebase Hosting page even if my-app-12345 is not using Firebase Hosting. Here is step-by-step method for doing that based on Firebase's documentation:
In Firebase project my-app-12345's console, click Hosting on the side menu.
When Set up hosting pop-up appears, click Continue. Then click Finish.
In Hosting page, click Connect domain.
When Connect domain pop-up appears, enter auth.mydomain.com. Then click 'Redirect auth.mydomain.com to an existing website' checkbox. Then enter my-app-12345.firebaseapp.com. Then click Continue.
When 'Add the TXT records below to your DNS provider to verify you own mydomain.com' pop-up appears, follow the instruction. And click Verify. (Verifying may take some minutes). Then click Finish.
Now auth.mydomain.com will be appeared in domain section with Pending status. It will soon be changed to Connected. And after some time, the NET::ERR_CERT_COMMON_NAME_INVALID warning issue will be gone.
P.S. With help of Firebase technical support team, I have got the answer to my own question.
just to clarify, as of Jan 6th 2020, the method above (using 'Redirect' within Firebase Hosting) doesn't work anymore.
Following something written in https://levelup.gitconnected.com/how-to-connect-a-domain-to-your-firebase-project-cd47373bad79 - we can see for Authentication, we need to use "Custom Domains" and not "Redirect"
This is because if redirection is used, the SSL signed between the exit and entry points of the custom domain and Google's authentication servers will fail the handshake.
In other words:
If you are setting it up for the first time:
In Firebase project my-app-12345's console, click Hosting on the side menu.
When Set up hosting pop-up appears, click Continue. Then click Finish.
In Hosting page, click Connect domain.
When Connect domain pop-up appears, enter auth.mydomain.com. Then do not tick 'Redirect auth.mydomain.com to an existing website' checkbox. Then enter my-app-12345.firebaseapp.com. Then click Continue.
If you've already setup a Redirect domain, and you cannot get it to work - you can simply edit the entry, and change to a "Custom" type.
Wait 10 ~ 30 minutes once that has changed to have this function properly.

Google+ Share Button isn't work

I'm doing a website where I have a Share button for Google+. I'm trying it in my localhost server and when I click the button, it turns red with an advice. In the advice I read these motives of error:
Server timeout: Check your Internet connection and try refreshing the
page.
Suspended profile: If your profile has been suspended, you
won't be able to +1 content.
Apps user: If your administrator hasn't
enabled Google+ for your domain, you won't be able to sign up for a
Google+ account to use the +1 button.
Blocked cookies: If you've
disabled 3rd party cookies in your browser you won't be able to use
the +1 button.
Logged out: If you've logged out of your account, you
won't be able to use the +1 button.
I checked the different motives and I don't know how I can check the Apps user...
This is expected behavior. Google has to be able to crawl your site to generate the preview snippet for the share. Google cannot crawl your localhost server.
To share pages, the content must be publicly accessible.

ASP.NET/SingleSignOn/SAML webapp Bypass Login screen based on URL request

Currently we have a typical web application, which all the clients access and login using their credentials.
One of the client does not want to login using their credentials, instead they will be passing username, fname, lname in the URL and they should be automatically be logged in if they have an acct or else we need create user account on the fly and log them in.
The web app should act the same way for the rest of the clients. How can this be achieved. Do we need to use any single sign on methodology (SAML, etc)?
Overview of requirement:
Request URL -> Determine if Client is A -> if yes then check the values passed in the url exists in the db -> if yes then log them in automatically -> if no create a record with the passed values and then log them in
---> if client is not A then take them to Login screen
If you are planning to base your decision only on some URL values to allow automatic login, you are creating a very biiig security loophole here.
Instead you should have some configurable mechanism, where system admin maps some IP addresses to specific user. This way when user requests for a page, you check if the IP from which request has come in, belongs to some specific client. If yes, then log him/her in else send them to login screen. This is also a bit of security hole, but a smaller one, because people will not gain access until they know which IPs are mapped to users and until they use some ip spoofing software.
Probably you can put a dual check of URL keys and IP mapping, that will make it tighter.
Best option is to use single sign on technologies like live id authentication. but it will require more efforts, and still requires users to login with live-id for the first time.
edit-->
If you are using your custom authentication mechanism, then you have 2 options
1. Change your login page to detect the request IP and have automatic login for selected users
2. Write a http handler which will check where the request is coming from and auto login the selected user accordingly.
I hope you understand what all things are involved in "Auto Login" which i am talking about. e.g setting the session variables/username, displaying the username on page etc.

Blocking all http requests if digital certificate is not present

In my app, the user can be authenticated with a login/password stored in a database or using its digital certificate.
In both ways, if the login succeeds a cookie is created and associated to the user.
FormsAuthentication.SetAuthCookie(model.UserName, false);
return RedirectToAction("Index", "Home");
I need this to be different.
If a user logs in with its digital certificate, I want to check if the certificate is there
otherwise it throws an error.
The concept is if the certificate is not there, this is because the user has left so nothing can be done.
Is that hard to do?
I found a simple solution to this.
On IIS, there is a way to set in the site advanced settings the connection time-out.
It is the period of time (in seconds) a connection can remain inactive before being disconnected.
Click on the site node, in actions pane click Advanced Settings, click the + on Connection Limits and set Connection Time-out (seconds) to the period of time you find relevant.
I set to 1;
Now basically every time the user calls an action it checks for the certificate. If it is there, the application continues normally.
It has worked for me because the digital certificate is a requirement. For those with normal login / password form auhtentication you need to find a better way or the user will be always redirected to the login page.

Resources