Getting basic authentication box appear when trying SSO (Websphere/keytabs) - websphere

I am trying to auto login via SSO on an app that is hosted within WebSphere. When i navigate to the SSO URL, it is asking me for a username and password - when i put the credentials in, this works fine. I believe that the issue is within the keytab but everything i have looked at online, seems to indicate that's fine.
The problem
I have an 2x app server that is hosted within Azure, domain joined to domain1.org
These two servers are joined to a load balancer, within Azure but using dns dev-domain1.org
Note: I have tested reverting all dns from dev-domain1.org to the AD domain domain1.org and SSO works.
SPN User
Created within AD: User: DOMAIN1.ORG\USERNAME with SPN HTTP/env.domain1.org
Created the keytab with the following command:
ktpass.exe -princ HTTP/env.domain1.org#DOMAIN1.ORG -mapuser DOMAIN1.ORG\USERNAME -pass [PASSWORD] -crypto all -kvno 0 -ptype KRB5_NT_PRINCIPAL -out "F:\PATHTOKEYTAB\.keytab "
Updated .conf file
~~ [libdefaults] ~~
default_realm = AD_DOMAIN
default_keytab_name = FILE:F:\IBM\WebSphere\AppServer\keytab
default_tkt_enctypes = rc4-hmac des-cbc-md5
default_tgs_enctypes = rc4-hmac des-cbc-md5
forwardable = true
renewable = true
noaddresses = true
clockskew = 300
[realms]
AD_DOMAIN = {
kdc = DC01.ad_domain:88
default_domain = ad_domain
}
[domain_realm]
.ad_domain = AD_DOMAIN
.dns_domain = AD_DOMAIN
Does anyone know how i should be setting up the keytab or even WebSphere itself if i want to use another domain for the URL that is different to the AD/internal domain?
Thanks in advance!

you stated.. if I want to use another domain for the URL that is different from the AD/internal domain?
Are you asking DNS domain or an AD domain?
For example, my URL has DNS with server1.ibm.com but the AD domain is domain1.com?
If so first you need to make sure in the AD domain DNS is able to lookup the URL server1.ibm.com
Next, you need to map ibm.com with AD domain domain1.com under krb5.ini file check this URL https://www.ibm.com/docs/en/was-zos/9.0.5?topic=server-creating-kerberos-configuration-file and example -dns austin.ibm.com|raleigh.ibm.com

Related

How to disable credentials input for HTTPS call to my WCF hosted in windows service

I'm just creating my first WCF project, so I have a lot of deficiencies in knowledge in this field. My problem is that when I'm calling my WCF url in web browser, I have to enter the credentials but I cannot even use my domain name and password, but I have to choose my personal chip card certificate and enter it's password. After that, everything work like a charm.
My final product should be installed on every user workstation in our domain for IT operations purposes only. So there will be some AD authorization after that.
About certificate... We have our own company root CA certificate, and every workstation have it's own certificate which is it's grandchild:
Example of our certificate tree:
COMPANYROOTCA >> COMPANYSUBCA1 >> WORKSTATIONNAME.DOMAIN (this one is used as WCF service cert)
This is what I have right now for hosting the WCF in my Windows service running under NetworkService Account:
serviceHost.Dispose(); //extension for close() and set to null
Uri httpsUrl = new Uri("baseAdress");
serviceHost = new ServiceHost(typeof(Service.myService), httpsUrl);
WSHttpBinding wsHttpBinding = new WSHttpBinding();
wsHttpBinding.Security.Mode = SecurityMode.Transport;
wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
WebHttpBinding webHttpBinding = new WebHttpBinding();
webHttpBinding.Security.Mode = WebHttpSecurityMode.Transport;
webHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
webHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
ServiceMetadataBehavior smb = new ServiceMetadataBehavior
{
HttpGetEnabled = false,
HttpsGetEnabled = true,
};
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection collection = store.Certificates;
X509Certificate2 cert = collection.OfType<X509Certificate2>().First(c => c.SubjectName.Name == "CN=WorkstationName.Domain");
store.Close();
serviceHost.Credentials.ServiceCertificate.Certificate = cert;
ServiceThrottlingBehavior throttleBehavior = new ServiceThrottlingBehavior
{
MaxConcurrentCalls = 16,
MaxConcurrentInstances = 26,
MaxConcurrentSessions = 10
};
serviceHost.Description.Behaviors.Add(throttleBehavior);
ServiceEndpoint soapEndpoint = serviceHost.AddServiceEndpoint(typeof(Contract.IMyService), wsHttpBinding, "soap");
ServiceEndpoint restEndpoint = serviceHost.AddServiceEndpoint(typeof(Contract.IMyService), webHttpBinding, "rest");
ServiceEndpoint mexEndpoint = serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpsBinding(), "mex");
restEndpoint.Behaviors.Add(new WebHttpBehavior());
tempAdminHost.Open();
So my question is: Is there any way, how to, for example, automaticaly get domain account which use the browser and call the url or any alternative how to still use HTTPS but without putting any credentials?
I didn’t see the way you use the credential to authenticate the client. the client credential type of the two endpoints you use to host the service are None. How does the browser ask you to input the credential? Besides, by default, If the server set up the ClientCredentialType to Windows, the client would use the current user as the credential. The current user’s password and account will be default credential when need to provide a credential.
One more thing to note, if you are simply prompted in the browser to select a certificate instead of the credential(user/password), as follows,
We may have configured the following parameter(clientcertnegotiation parameter).
netsh http add sslcert ipport=127.0.0.1:8000 certhash=c20ed305ea705cc4e36b317af6ce35dc03cfb83d appid={c9670020-5288-47ea-70b3-5a13da258012} clientcertnegotiation=enable
Because the way you use to provide a certificate to encrypt the communication is not correct.
serviceHost.Credentials.ServiceCertificate.Certificate = cert;
We need to bind the certificate to Port.
https://learn.microsoft.com/en-us/windows/desktop/http/add-sslcert
when hosting the service in IIS, we accomplish it by the below UI.
And the parameter configuration depends on the below.
So I suspect the process that binds the certificate to the specified port is completed by IIS. and the parameter should be ignored.
Feel free to let me know if there is anything I can help with.

Multi-Tenant Azure AD authentication with IdentityServer4

I've configured Identity Server 4 and using Azure AD Authentication. Everything works fine if I use a tenant specific Authority URL in identity server. With that, only a user from that tenant can login. I would like to allow multiple domains to login and would like to validate the issuer in the backend.
To support that I need to use common login endpoint for Azure AD and after I login I get the following error when it redirects to signin-aad endpoint of Identity Server. What configuration should I do so that I can validate the issuer manually?
SecurityTokenInvalidIssuerException: IDX10205: Issuer validation failed. Issuer: 'https://sts.windows.net/94b73406-72db-4abb-a142-adfdfdfdfdbc/'. Did not match: validationParameters.ValidIssuer: 'null' or validationParameters.ValidIssuers: 'https://sts.windows.net/{tenantid}/'.
Microsoft.IdentityModel.Tokens.Validators.ValidateIssuer(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
If your domains can grow dynamically at runtime then set ValidateIssuer to false in the TokenValidationParameters. If you have predetermined set of domains then add them all to ValidIssuers.

Getting ACME error when going for new domain cert

I am sure I am doing something stupid here, but I have been going around in circles for a bit. I have Traefik up and running with a cert for url1.ccsilab.com. I am trying to add for url1.ccsicloudsolutions.com that goes to the same place. I tried with two frontends pointing to one backend and now I have two frontends each pointing to their own identical backend. I am getting the following error.
Oct 3 16:15:30 ip-10-230-0-10 traefik[27166]: {“level”:“error”,“msg”:“Unable to obtain ACME certificate for domains \“ccsicloudsolutions.com,url1.ccsicloudsolutions.com\” : unable to generate a certificate for the domains [ccsicloudsolutions.com url1.ccsicloudsolutions.com]: acme: Error -\u003e One or more domains had a problem:\n[ccsicloudsolutions.com] acme: Error 403 - urn:ietf:params:acme:error:unauthorized - Invalid response from http://ccsicloudsolutions.com/.well-known/acme-challenge/UoyASm_w_5Xkdv-xVx8NKi3ndbZ81tls_0eHO8iAD0I [34.194.40.15]: 404\n”,“time”:“2018-10-03T16:15:30Z”}
Below is the acme portion of the config:
[acme]
email = “xxxx#yyy.com”
storage = “acme.json”
caServer = “https://acme-v01.api.letsencrypt.org/directory”
entryPoint = “https”
[acme.httpChallenge]
entryPoint = “http”
[[acme.domains]]
main = “ccsilab.com”
sans = [“url1.ccsilab.com”]
[[acme.domains]]
main = “ccsicloudsolutions.com”
sans = [“url1.ccsicloudsolutions.com”]
Most likely the domain ccsicloudsolutions.com doesn't points to traefik or access to the resource which Let's Encrypt's verification server requested, requires authentication (Error 403).
Make sure the DNS records for the domain are correct and that the http entrypoint doesn't require authentication.
This error message comes up, when Let's Encrypt fails to verify the ownership of the domain.
Also, I'd use the new Let's Encrypt endpoint (https://acme-v02.api.letsencrypt.org/directory)

Insecure Login Blocked: You can't get an access token or log in to this app from an insecure page. Try re-loading the page as https://

I am implementing Passport Facebook Authentication by linking the Facebook Authentication API route to a button using href like:
Facebook Login
When I click on the button, it redirects to the Facebook Authentication page. But on the page, an error message is displayed saying something like "Insecure Login Blocked: You can't get an access token or log in to this app from an insecure page. Try re-loading the page as https://"
How can I fix this issue?
Amazingly I just started trying to do the same thing like an hour ago and have been having the same issue. If you go into the FB developer portal and go to Settings under Facebook Login there's an option to Enforce HTTPS.
Further Investigation Showed:
"Enforce HTTPS. This setting requires HTTPS for OAuth Redirects and pages getting access tokens with the JavaScript SDK. All new apps created as of March 2018 have this setting on by default and you should plan to migrate any existing apps to use only HTTPS URLs by March 2019. Most major cloud application hosts provide free and automatic configuration of TLS certificates for your applications. If you self-host your app or your hosting service doesn't offer HTTPS by default, you can obtain a free certificate for your domain(s) from Let's Encrypt."
Reference: Login Security
Since you're using passport, also check your auth.js settings, or where ever you keep these settings. Even if your website has a certificate, the following code will still fail:
'facebookAuth' : {
'clientID' : '.............', // App ID
'clientSecret' : '............................', // App Secret
'callbackURL' : 'localhost:9999/auth/facebook/callback',
'profileURL' : 'https://graph.facebook.com/v2.5/me?fields=first_name,last_name,email',
'profileFields' : ['id', 'email', 'name']
},
The problem lies with the callbackUrl.
'callbackURL' : '/auth/facebook/callback'
'callbackURL' : 'http://localhost:9999/auth/facebook/callback'
The statements above will both fail. The callbackUrl needs to start with https. The first one will try to load http://localhost and append the callbackUrl. The second one obiviously loads the full url with http, and both fail to connect with FB. So try one of the following. If your site has a certificate, provide the full url. If you're testing this on a localhost, create your own certificate and access it by https like:
'callbackURL' : 'https://example.com/auth/facebook/callback'
'callbackURL' : 'https://localhost:9999/auth/facebook/callback'
Since Facebook have been requiring usage of HTTPS for our redirect URIs we can use ngrok at localhost for start up a local secure HTTP tunnel. It is a clean and fast suggested alternative for now.
Get official ngrok package
Unzip to your preferred directory
unzip /opt/ngrok.zip;
Make your first HTTP tunnel: /opt/ngrok http 3000
See more great use cases in ngrok docs.
There are 2 ways you can solve that:
First:
You can go to your google Passport strategy and add proxy: true
passport.use(
new FacebookStrategy(
{
clientID: facebookID,
clientSecret: facebookSecret,
callbackURL: "/auth/facebook/callback",
proxy: true
}
)
);
What happens most of the time is that, when you deploy or app through Heroku, for example, they have a Proxy that allows Heroku to direct the requests to your specific server and Passport assumes that if your request goes through a proxy it might not be safe (So... No https).
The second way you can solve that is by using a specific path for your callbackURL.
For example, instead of using:
callbackURL: "/auth/facebook/callback"
you would use:
callbackURL: https://mydomain/auth/facebook/callback
Keep in mind that if you are going to use this approach you might need to create environment variables to hold the values of your specific redirectURL for development as well as for production.
To fix, for local development, generate ssl certs on your machine. Run the commands below(tested on Mac High Sierra, you will need the openssl lib installed on your os) to create a cert.pem and a key.pem file in your working directory.
openssl req -x509 -newkey rsa:2048 -keyout keytmp.pem -out cert.pem -days 365
openssl rsa -in keytmp.pem -out key.pem
Change your node http server to use https. You will need to import the https module in place of the http module.
const https = require('https')
const path = require('path')
const fs = require('fs')
const options = {
cert: fs.readFileSync(path.resolve(__dirname, '<path_to_your_cert.pem>')),
key: fs.readFileSync(path.resolve(__dirname, '<path_to_your_key.pem>'))
}
const server = https.createServer(options, <your_handler_or_app_eg_express>)
server.listen(<your_prefered_port_number>)
Go to the app on your facebook developer console and set the Valid OAuth Redirect URIs to the https version of your localhost domain. Do same for the app domain and site url.
In my case, I modified my package.json file.
"start": "node scripts/start.js" =>
"start": "set HTTPS=true&&node scripts/start.js"
I hope help you.
This for php sdk reference
Now https is required for the web-application to login via Facebook.
Following procedure is required get valid authentication from Facebook.
Basic Seetings
set App Domains as your root domain (www.example.com)
Privacy Policy URL (https://www.example.com/privacy-demo/)
Terms of Service URL (https://www.example.com/terms-demo/)
Set Category
Site URL (https://www.example.com/facebook-login/) facebook-login this folder contain my all facebook login files
Advanced
Server IP Whitelist (your host ip address 124.25.48.36)
Products below Facebook login settings
Valid OAuth Redirect URIs (https://www.example.com/facebook-login/fb-callback.php)
Quick start
Select website put site url (https://www.example.com/facebook-login/)
Save all changes and live your app (ie: on your app) Now your app status will live.
You can refer this code https://github.com/facebook/php-graph-sdk
use a vpn worked for me cyber ghost is free try it
In your passport setting change your redirect url to some https://someUrl
'https' is important

Spring Web Application Login with Active Directory

I had configured active directory login with spring and able to do login and fetch attributes but the problem is I have to submit raw password from my browser to server as AD requires it.
I just checked that when I posted from browser as SHA2 encoded password and passed it to AD login it gives me authentication failure. Due to security reason I need to encode password as SHA2 before posting it to Server. Is there any way to work around?
AndFilter filter = new AndFilter();
ldapTemplate.setIgnorePartialResultException(true);
filter.and(new EqualsFilter("userPrincipalName", authentication.getName()));
boolean authenticateUser = ldapTemplate.authenticate("", filter.toString(),password);
The documentation doesn't say anything about accepting an encrypted password.
The password may already be encrypted when transmitted, though I don't know off hand how that works. If you want to make extra sure, you can connect via LDAPS (LDAP with SSL). This page (under 8.1.1) makes it look as easy as replacing "ldap://" with "ldaps://" and adding the port on the end of the server name:
ldaps://myserver.example.com:636
Port 636 is the default port for LDAPS.

Resources