SiteMinder and HTTP Client - User Login Info - httpclient

We have a Portlet running on Java/J2EE technology. It interacts with another application/system through HTTP request that requires user authentication. The current solution retrieves logged in user's user name and password from the Portal, and passes this information to back end systems using "HTTPClient" API's to retrieve content based on user's authentication and authorization.
There are efforts to enable site minder for the Portal. With site minder enablement, the Portal no longer provides logged in user's user name and password. The ideal way would be that back end application also has site minder enabled so that Portlet could pass the login token or cookie value.
Looking for interim approaches until the back end application is SiteMinder enabled. Is there a way we can enable/force user to enter user name and password ? I cannot think of such possibility because the Portlet code (using HTTP Client accesses the back end URL of the application, its not the browser). One possible way I can think of is, develop a new screen(UI) to have user enter user name and password within the Portlet and use that to authenticate with back end system through Java code. Please let me know if any other ideas.
Also, let me know if the question is confusing, I will provide more details.
Thanks

Siteminder can provide user information dynamically to connected applications in HTTP headers (uid, email address, etc.). This behaviour is configured on the Siteminder Policy Server. By default, the HTTP header SM_USER (or similar) contains the username of the authenticated user.
Then, you have to adapt your portlet code to fetch those headers from the request and feed it to the back-end application like you used to.

I wouldn't advise the use of the SM_USER header for tracking users. SM_USER contains the ID that was provided to the credential collector, and will change based on the type of authentication scheme used.
Example:
If you have an HTML forms based auth scheme that collects email address instead of UserID, the email address will be sent in the SM_USER header. In the case of an X.509 auth scheme the SubjectDN from the certificate will be in the SM_USER header.
The better choice would be to use the SM_UNIVERSALID header as that will always contain the Universal ID attribute. The Universal ID attribute is configured in the User Directory object (typically this is set to "uid").

Related

Restrict front client connexion with groups / roles in a realm

I'm looking for a way to restrict user access to specific clients in a realm.
I know I can do it with client where Authorization is enabled (fine-grained authorization support) but it doesn't work when trying to connect from front (client need to be public and not confidential).
I'm using a javascript application to login from front-end.
Is there a way to enable Authorization for public client or a work around ?
Thanks.
I'm not sure if this will totally answer your question because it's still not specific enougth but it may give you some further help.
In case you're new to the topic, please see difference between public and confidential clients here.
The current best practice for public clients like HTML/Javascipt applications is to use OpenId Connect with the Authorization Code Flow + PKCE. HTTPS is of course a must have. I recommend you use a javascript openid connect adapter for this like the following for example:
https://github.com/panva/node-openid-client
Basically your authentication / authorization flow is shown here:
When the user wants to login from your frontend client application first a unique verifier is generated which is only available to the exact user / browser session. This value get's hashed as a code challege. Then the user gets redirected to the login page of your authorization server (Keycloak for example) passing some parameters like a redirect uri and the challenge.
With successful login the user get's a session at the keycloak server which also stores the hashed challenge. Then the user gets redirected to given redirect uri (a path in your application) together with a code to obtain an access token. Back in your application you application uses the original value together with the code to get the actual token. The authorization server ckecks the value against the stored challenge and geturns the access token if it matches. You see the extra verifier is to prevent that anybody compromises your code fragment to obtain a token on your behalf.
Now you have an encoded access token in your browser app. Note the token itself is normally only encoded not encrypted but it can be signed. Those signatures can later be used from your backend to ckeck the token integrity but we will come to that soon. Roles, claimes, scopes and so on included in your access token tell you the privileges of the user/identity. You can of course use them to enable/disable functions in your app, block routes etc. but in the end client protection is never really effective so your real authorization ande resource protection happens at your resource server which is your backend (node, .net core, java etc.) maybe a restful Web Api. You pass your access token as a part of the http request header with every request to the backend. Now your backend checks the token integrity (optional) expiration time etc. analyzes scopes, claimes and roles to restrict the resource access.
For example a simple GET myapi/car/{1} may only need a token or can even be annonymous while a POST myapi/cars or PUT myapi/car/{1} may need a special role or higher privileges.
Does that help you out?

keycloak - realm resolution based on username (email address)

I'm working on a multi tenant project where usernames are actually their email addresses and the domain of the email serves as a tenant identifier.
Now in keycloak I'll have different realms per tenant, but I want to have a single login page for all tenants and the actual realm that will do the authentication to be somehow resolved by the username (email address).
How do I go about doing that?
I found a thread on the mailing list (that I cant find now...) that discussed the same problem. It was something along the lines of - create a main realm that will "proxy" to the others, but I'm not quite sure how to do that.
I think Michał Łazowik's answer is on the right track, but for Single-Sign-On to work, it needs to be extended a little.
Keep in mind that because of KEYCLOAK-4593 if we have > 100 realms we may have to have multiple Keycloak servers also.
We'll need:
A separate HTTP server specifically for this purpose, auth-redirector.example.com.
An algorithm to determine the Keycloak server and realm from a username (email address).
Here would be the entire OAuth2 Authorization Code Flow:
An application discovers the user wants to log in. Before multiple realms, the realm's name would be a constant, so the application would redirect to:
https://keycloak.example.com/auth/realms/realname/protocol/openid-connect/auth?$get_params
Instead, it redirects to
https://auth-redirector.example.com/?$get_params
auth-redirector determines if it itself has a valid access token for this session, perhaps having to refresh the access token first from the Keycloak server that issued it (the user could have logged out and is trying to login as a different user that is served by a different realm).
If it has an valid access token we can determine the Keycloak server and realm from the username or email address in the access token and redirect to:
https://$keycloak_server/auth/$realm/realname/protocol/openid-connect/auth?$get_params
from here, the OAuth2 Authorization Code Flow proceeds as usual.
Else if it doesn't have a a valid access token, the auth-redirector stores the original app's $get_params as session data. It presents a form to the user asking for a username. When the user submits that, we can determine the Keycloak server and realm to use and then auth-redirector itself logs in to the Keycloak server using its own $get_params. Once the auth-redirector gets a call-back, it retrieves the access+refresh token from the Keycloak server and stores them in session data. It then, finally, redirects back to that same keycloak server and realm with the callers original $get_params (from session data). And the OAuth2 Authorization Code Flow proceeds as usual.
This is definitely a hack! But I think it could work. I'd love to try it out some day, time permitting.
Other hacks/solutions are needed for other OAuth2 flows...
The idea from the mailing list is to write a service (let's say auth-redirector.example.com) that has a single input field for email, finds realm based on domain and redirects to that realm's keycloak endpoint (e.g. auth.example.com/auth/realms/realm-name/etc…) while keeping all GET params.
You can find examples of direct login/registration URLs here: https://lists.jboss.org/pipermail/keycloak-user/2016-July/007045.html
One usability problem is that users would have to provide their email twice, I have not yet found a way to pass the username via the login URL.

Identity Server 3 - Silent sign-in / sign in without login page. Including single sign on

I have come across a number of articles that discuss a similar matter but I cannot find a definitive answer.
My company would like to begin using Identity Server 3, however one of the requirements is to be able to authenticate an external user without them having to manually enter their credentials.
This must be capable of providing single sign on capabilities also as we have 3 different systems and our users should only have to sign in once.
Essentially, the external user has their own CRM.
The CRM holds their username and password for our software.
They then click a button in their CRM to launch our application
This redirects them to our website with a payload containing their credentials
We call a web service to authenticate the user
It is fundamental that we do not change this process for our partners.
Can I implement a custom service provider to provide the authentication or is there some other way of achieving this? If so, could you point me in the right direction for how this can be done?
Many thanks
Craig
I would assume that you'd create a mechanism for their CRM to get a token at the time the client logs into their site and then have them send that token via url to your callback page. This would use the machine-to-machine type grant, or the client-credentials flow. Then that page could validate the token and log the user in. There would have to be some sort of unique identifier between the two systems like email or something. Just an idea.

Connection to MSSQL database for secure login in Objective C

I want to make an app having financial Transactions for iPhone.So, my first target is to make a login page(and that's where my problem starts):-
The Admin or customer Details are stored in MSSQL DB.Now, when the client enters his username and password in my app, i want to verify these Credentials. So how can i do this?
Acc. to my little knowledge, i cannot connect to the DB directly, I need some web service or something as a middleware(but don't know what).I cannot parse the url directly to check the credentials as it will not be safe.Did we have to Encrypt the Credentials of client and if yes then how can i retrieve and verify the Login?
Any Sample, Links or anything will be helpful.
Create a .net site with a login.aspx web service page where you will handle authentication for the app. Make sure to get a HTTPS/SSL cert set up on your site as well.
Call me overly cautious, but I hate the idea of direct web server database access from a client app, I always like a middle layer of control/protection.
Edit
for example, you app can make server calls similar to this (using POST of course): yoursite.com/webservice/Login.aspx?username=chucknorris&password=somepassword&appkey=679384820473487746
Then on your Login.aspx page (or other pages for that matter) you would check for the POST variables (username, password, etc) and ask the database if they match. If they do then have the page return a success message, or do whatever additional processing you desire.
On multiple page requests within a certain amount of time, you can optionally use session states or go the more RESTful type of route, both are easily researched via Google.
POST + SSL is a must for basic security measures.

Cookie based SSO

How can I implement a cookie based single sign on without a sso server?
I would to share the user logged in across multiple applications using
only a cookie on the browser.
In my mind it's working like this:
user logs in an application
the application verifies the credentials and then it setting up a cookie on
the browser storing the username (that could be coded with a private key)
if the user opens another application, it searches the cookie and reads
the username on the value (using the key for decode the string)
In this solution a user may see the browser cookie (of a another user)
and take the string codified of the username. Then he could adding it on
an own cookie (no good!).
There's some secure way to do this? With a timestamp based control or
something like this?
Thanks in advance.
Bye
P.S.
I know that my english isn't very well.. sorry for this!
This is impossible. Cookies are unique to each domain, and one domain cannot read another domain's cookies.
I think the answer comes a little late, but maybe I can help someone.
You can have a cookie / localStorage in an intermediate domain connected to the home page using an iframe
1) Login
The login form in any of your domains deposits the identification token in a cookie on sso.domain.com by an event (postMessage)
2) Verification
domain1 and domain2 include a iframe pointing to sso.domain.com, which reads the token and notifies the home page
To simplify development, we have released recently a cross domain SSO with JWT at https://github.com/Aralink/ssojwt
There is a simple solution without using an sso server, but not with 1 common cookie, as we know that cookie's are not shared between domains.
When the user authenticates on site-a.com, you set a cookie on site-a.com domain. Then on site-b.com, you link a dynamic javascript from site-a.com, generated by server side script (php, etc) who has access to the created cookie, and then copy the same cookie on site-b.com on the client-side using js. Now both sites have the same cookie, without the need of asking the user to re-login.
You may encrypt/encode the cookie value using a method that both site-a and site-b knows how to decode, so that site-b will be able to validate his cookie copy. Use a common shared secret that without it will be impossible to encode or decode.
You see that on the 1st page load of site-b.com, the cookie is not present, therefore if you see necessary, you may want to do a page reload after setting the cookie.
I have done something similar. There is a PHP application where the user logs in, the system contact a web service and then the service checks the user's credentials on the Active Directory. When the user is authenticated, his PHP session is stored in the DB. Another web application can read the PHP session from the cookies and uery a web service in the PHP applicaiton, the PHP application check the session in the database and return the user id. In this way I have a SSO using SOA.
Do not rely on the user id stored in the browser, is a security error, at least encrypt the id.
The best solution would be to put the login form and session storage in the same application, then this application can provide services to other applications.
And use HTTPS for the kind of infomation exchange.
The cookies can be read only if the belongs to the same domain, for instance:
intranet.example.com
crm.example.com
example.com/erp
You can access cookies across subdomains, but I do not think using browser cookies is a great solution. You really don't need a "SSO server" to implement a single sign-on. It is fairly easy to come up with a payload that both applications recognize. I have seen custom SSO solutions that transmit the payload using XML over HTTPS.
Here is a solution (which will hopefully get heavily scrutinized by security gurus on here):
Have each domain store user data in a similar cookie, and when a user want to jump from one domain to another without authenticating themselves on the new domain, provide a "jumplink" with an encrypted token in the query string. The new domain would decrypt the cookie, and figure out who the user is, then issue them a new cookie for that domain. You would want the "jumplink" to have a very short expiration date, so I would not generate them right into the page, but generate links to a "jumplink" generator and re-director.
This might not be necessary, but the receiving page for the "jumplink" could make a web service call back to the originating domain, to verify the authenticity of the encrypted token and the whether it's expired.
I think this solution would be susceptible to man-in-the-middle attacks (not sure if it would be more so than other auth mechanisms which are currently popular), but you could incorporate a client MAC address and IP address into the encrypted token for extra security.