Using SPNEGO and LTPA in WebSphere - servlets

General question. Server admin setup SPNEGO. The LTPA bullet is marked under Global Security in admin console. My understanding is that SPNEGO captures username from an initial sign-on (ie network). Later, if user goes to an app's URL, few of the many things happening is SPNEGO is going through user's ldap groups (admin console-securtity roles) trying to find group that is tied to app's role names. If match is found, user authorized and can go directly into app without having to use login form to enter credentials. But have problem trying to implement this. Checking HttpServletRequest - getUserPrincipal().getName() and getRemoteUser() at front end of app are coming up null. If SPNEGO is in fact setup correctly, should a null ever be found?

You are confusing a few things. SPNEGO is a mechanism to pass user authenticated in the Kerberos realm to the given service without need to pass user password. It has nothing to do with authorization - this part is done by WebSphere security service based on the id retrieved from the request (in short).
Null username usually is effect of not enabling Application Security in the server or not protecting application with Java EE security (security constraints defined in the web.xml).
For some basic information about SPNEGO in WebSphere, check the following page Single sign-on for HTTP requests using SPNEGO web authentication

Related

OAuth2 protected API. How to allow customer's to SSO using its own authorization server?

I have an Angular Single Page Application (SPA) talking to my ASP.NET API.
The API is protected by my own Oauth2 server (IdentityServer4).
One of my customers (let's call him X) wants SSO: Their users on my platform would sign in on their server instead of using the login form in my app that connects to my IdentityServer.
Each customer has its own subdomain for the Angular SPA (e.g. x.myapp.com). Therefore I can easily redirect X's users to their server's authorization page to approve my API, based on the hostname.
However the API itself uses one common hostname for all customers(api.myapp.com). Customers are distinguished by the Origin header of the API call (x.myapp.com) during the login call (and a few other unprotected calls) and by the Bearer token for protected calls to the API.
How does my API introspect the Bearer access token? Who should know which server to query ?
Is it the responsibility of the API server? Or can I tell my IdentityServer about X's oauth2 server ?
X's users would also be defined on my platform since we need specific info (such as config of roles on the platform). My current setup implies specific claims (such as user id) that allow my API to know what the user can do. Obviously, X's server will not provide the same claims. How can I connect the dots ? e.g. get some standard claim from X's server (username, email, whatever) and match it to my list of users.
Note: This question is similar but the answer is not accepted and seems to imply that the provider of both identity servers is the same (not the case here).
Formatting my comments as an answer:
From reading your question it's pretty much clear to me that you could benefit from what is know as Federated identity.
As you said, one of your customer want to achieve SSO - They want users to login using their existing accounts and be able to user your systems normally.
Since you already have an IdentityServer in your domain, what you can do is delegate the login part to the customer's side (whatever they do it). This is illustrated in the Identity server documentation Federation Gateway.
Basically, the approach is that upon hitting the "login" button in your front-end, you would redirect the users to your Identity Server passing some special params (prompt and acr_values for ex) which in turn, tells identity server to redirect the user's to the external Identity provider (the customer's). After a successful login, you have a chance in Identity Server to augment the claims, maybe using something they returned or anything really. Then the process is as normal - you return a JWT Token generated by your Identity Server
The benefit of doing this is:
Your SPA/API doesn't have to change. You will still work with your own bearer tokens and can continue doing authN/AuthZ as before.
You have a chance to add claims that might indicate where this user is coming from if needed
If your customer's server changes, you don't have to worry much, apart from maybe some tweaks related to returned claims
They don't necessarily need to use OpenId/OAuth on their side for this to work
Useful things you probably will need is some params to pass during the call to the authorize endpoint in Identity Server. (acr_values and prompt).
You can also check this in the quickstarts, by looking at Sign-in with external providers (which is pretty similar to what you want)
Now to your individual points:
Your Identity Server should be the "bridge" between you and the customer's "identity provider".
Upon a login from an external provider (X), you need to somehow identify the user on your platform. You could use email or, even better, if X is already using OpenId/OAuth they might give you the sub claim which is the user id on their side. At this point you need some sort of agreement with them otherwise this might be flaky/unreliable for both sides.
In a more "advanced note" you could also add to your tokens some sort of claim that tells you who is the source provider of this user. Here the source provider would be X. This is useful because you might want, for example, configure allowed identity providers in your app, or maybe enable features only for certain providers. Like, ppl logging in with Google might only see certain parts of the app.

What is this Authentication model called in the ASP.NET world

I know ASP.NET supports various authentication models like, Windows, Forms, passports and recently Claims.
I have an asp.net that prompts user to enter user name/password to login, it then compares the input username/password with the entries inside the user table of the application's Database. So, my question is, what is the term/name for this kind of authentication model? Where does this fall in the above mentioned ASP.NET supported authentication model?
I also see that many of the internet sites that I know uses this same approach.
(note: I'ev kept my App simple, of course it has user registeration/add page, profile table to authorize users, etc)
Windows, Forms, Passport, Claims, etc.. authentication are BROWSER authentication schemes. They are the mechanism the browser communicates with the server to present credentials. They have nothing to do with databases or any other storage mechanism (well, mostly..). Those are just implementation details.
FormsAuthentication uses a cookie to store an encrypted value that tells the server that the user has been authenticated. How the user is authenticated, be it by comparing things to databases, using a service, etc.. is all irrelevant if the end result is that a FormsAuthentication cookie is issued.
WindowsAuthentication is a little different in that the browser and the web server communicate to share a Kerberos ticket to verify identity, or the user enters the username password into a box that the server requests the browser to pop up. In this mode, the server itself manages the way that authentication occurs and the app isn't involved.
BasicAuthentication uses an HTTP Header to send the password in cleartext, well, technically it's an encoded password, but it's well known so anyone can unencode it. Again, the actual method that it stores the data is up to the server, and the server does this without an applications knowledge. The important part is that it's accomplished via an HTTP Header.
The same is true of other types of authentication, which are all just variations on the cookie and/or header mechanisms.
The point here is that Authentication is about how any given HTTP request identifies who the user is to the server, and ultimately the application. Not how the data is stored, or validated. So, since you did not tell us how the server and browser communicate, we can't tell you how your authentication is defined, although almost certainly it is a variation of FormsAuthentication.
EDIT:
Just a little history lesson. The reason it's called FormsAuthentication is because the authentication system does not use a pop up dialog box from the browser to enter credentials, but typically the web page provides an HTML Form for the user to enter credentials. The browser is not really involved in the authentication process at all, other than for passing a cookie as requested.
It should be more accurately called "CookieBasedAuthentication", but the name has stuck and will probably stay what it is. ASP.NET provides a specific implementation called FormsAuthentication, but you can do the same thing with any cookie based authentication scheme (although I do not recommend rolling your own, you will almost certainly make security mistakes).
Some people think that storing a flag in Session is good enough. Do not, under any circumstances, ever use Session to store authentication information. Session cookies are not encrypted and are easily stolen and/or spoofed. Use a well known method.
The other answers might have already showed most of the details. But if we categorize carefully on IIS and ASP.NET levels, below are the differences you should pay attention to,
IIS Authentication
This occurs first, as HTTP packets arrive at IIS level first. IIS supports several ways,
Anonymous (the anonymous user account configured in IIS configuration)
Windows (browser side user)
Basic (browser side user)
Digest (browser side user)
How those authentication methods work at packet level requires you to capture network packets and dive into the conversation at that level.
The result of this authentication is that IIS generates a user token and passes on to ASP.NET pipeline.
ASP.NET Authentication
ASP.NET has several authentication methods of its own,
Windows (here ASP.NET trusts and interprets the user token IIS passes, and determines which ASP.NET user identity should be created and which roles it supports, without doing further authentication on ASP.NET level.)
Forms (based) authentication (where ASP.NET ignores the user token, and uses cookies or similar mechanism to build a high level authentication approach. On IIS side you usually set anonymous authentication.)
Claims based authentication, OpenID, OAthen and so on are similar to Forms based, where they don't care much about the user token generated by IIS.
It is possible to use non-anonymous on IIS plus non-Windows on ASP.NET side to set up the so called mixed authentication.
All the Authentication methods that require the user to input a Username and Password that you maintain are a form of Forms Authentication. This is because you are asking them to fill out a form (Username and Password) in order to authenticate them.
Read more about it Here or Here.
Edit: The answer provided by Mystere Man is much more complete and accurate than mine.

Access unsecured resource that uses EJB after succesful JAAS login (WebSpere 7)

I have a web app that uses ejb (separately deployed), login is handled via JAAS. Can I get caller principal when accessing unsecured url, after authentication, during current session?
More details follows.
ejb:
Simple EJB is registered in the WAS (WebShere 7). It has one method that prints out the principal:
ctx.getCallerPrincipal().getName();
webapp:
The web application (deployed separately) has 2 servlets. One is mapped to unsecured path and the other one is secured, i.e. its path is registered in web.xml under <security-constraint>. Servlets have the EJB injected into them (via #EJB annotation). EJB binding works. Webapp uses form base authentication, using JAAS: there is a login form with j_security_check, j_username etc. WAS is configured to use security (using local operating system) and webapp role is mapped to All Authenticated in Application's Realm.
login works:
To keep it short, above configuration works: if I access the secure page (/secure/index.html), WAS displays the login form (if not already logged in), where I can enter my username and password and continue with the execution; EJB is called and the principal is fetched, printing out my username. As expected.
accessing unsecured resource after the login
However, if I access the unsecured servlet (/index.html), EJB *cant get the caller principal and prints out: UNAUTHENTICATED for user name. This happens regardless I am logged in.
question
Can I get caller principal somehow when accessing unsecured url, after authentication, during current session?
I am not sure if JAAS defines this use case in the spec? Or should I take care of this manually (eg using session and injecting caller principal into thread local).
You probably should change default behavior for web authentication which is not to provide authentication data for unprotected URLs. The option "Use available authentication data when an unprotected URI is accessed" should be enabled.
Overall, I strongly recommend reading WebSphere Application Server V7.0 Security Guide for understanding how security works in WAS.

ASP.NET & Microsoft Exchange: autentification and security practice

I'm writing service which will use for sending emails in my ASP.NET project. I tested two approaches for autentification on Exchange:
Since my service is running under
local user I allowed for it an
anonymous access and pass login and
password to Exchange Server.
Another way is domain authorization
on Exchange: before I invoke
smtpClient.Send() method I
impersonate(in code) an exist domain
user with access rights to sender
mailbox.
All of this ways works well but I really little confused how it should be as a good scenario. If I have a feature for sending mail on my ASP.NET site and Exchange Server -- what type of autentification on Exhcange user policy is preferable (1 or 2, ...)?
Option 3: Configure your service to run with a domain user account.
If so, this would be the preferred option, IMHO. Exchange can then be configured to allow access to a know domain user, avoiding the need to require anonymous access and, importantly, you don't have to secure away credentials in your service configuration in order to impersonate a domain user.
Indeed, you could configure your service to run under the security context of the user that you're impersonating.

Securing ELMAH with no admin accounts

I'm wanting to secure ELMAH in an internet facing application. The system uses Forms Authentication, but doesn't currently have any non-user accounts (e.g. Admins). The user accounts are set up in an automated fashion.
I don't really want to shoehorn any admin accounts into the system (the current DB schema for the users would be quite inappropriate for storing an admin user in), so I was thinking of corrupting the Forms authentication by checking for an SSL client certificate. If I pick all the right options in IIS, I believe I can ensure that only certificates issued by our internal CA (currently used for non-production sites needing SSL certs) will get passed through to ASP.Net.
I can then use the presence of a Valid ClientCertificate (checking IsPresent and IsValid properties of Request.ClientCertificate) to know that this is a connection from an internal user, and set the Forms Authentication cookie as "Diagnostic" or "Admin" (Or any other special username), and then secure elmah.axd using any of the usual methods suggested for doing it via Forms Authentication.
So my question is - am I overcomplicating things, missing something obvious, opening a massive security hole, etc?
Why don't you just store an admin user account credentials within Web.Config and lock down the URL using Forms Authentication anyway?
Edit
Ok, if the application is entirely internal anyway, why not secure a subdirectory of your site (e.g. myapplication.domain.com/exceptions/elmah.axd or even just myapplication.domain.com/elmah.axd) using Active Directory and set authorisation through IIS?

Resources