keycloak provides different issuer for frontend and backend - keycloak

I am new to keycloak, I am using keycloak for both frontend and backend application but I am getting the different issuer in the token generated by keycloak when decoded in jwt.io.
Front end:
the issuer is the same as the base URL of the frontend application
For example:
If the front-end URL is https://example.org/portal then the issuer is the same as https://example.org/auth
Request via postman:
the issuer is the internal DNS name
I have tried below ways,
Proxy redirection(With preserve host) - Which generates the issuer with frontend base url.
Proxy redirection without preserving host - Which expects the private DNS to be resolved at front end application
Played around the keycloak configuration - updated frontendUrl to https://example.org/auth and forceBackendUrlToFrontendUrl to true which resulted in the same issuer both the backend and frontend but no hostname like https:/auth/relam/external(Refer #2 in reference).
Expected outcome:
I need the private DNS to be issuer it both the request from frontend and backend(for now it works direct backend request)
Thanks in advance.
Reference
https://github.com/keycloak/keycloak-community/blob/master/design/hostname-default-provider.md
Code block
<spi name="hostname">
<default-provider>fixed</default-provider>
<provider name="fixed" enabled="true">
<properties>
<property name="frontendUrl" value="https://example.org/auth"/>
<property name="forceBackendUrlToFrontendUrl" value="true"/>
</properties>
</provider>
</spi>

Related

Keycloak openid-connect/3p-cookies/step1.html not found error

I am trying to configure my Keycloak hostname. I have a frontend URL for the public requests and an admin URL not publicly exposed :
Frontend URL : http://localhost:8080/auth
Admin URL : http://localhost:8081/auth
I have the following hostname configuration in my standalone-ha.xml file :
<spi name="hostname">
<default-provider>${keycloak.hostname.provider:default}</default-provider>
<provider name="default" enabled="true">
<properties>
<property name="frontendUrl" value="${env.FRONTEND_URL}"/>
<property name="forceBackendUrlToFrontendUrl" value="false"/>
<property name="adminUrl" value="${env.ADMIN_URL}"/>
</properties>
</provider>
...
Now I can't access the Keycloak admin console (localhost:8081/auth/admin). It only loads a white page with the following error in the console :
GET http://localhost:8080/auth/realms/master/protocol/openid-connect/3p-cookies/step1.html?version=6rmi9 404 (Not Found) check3pCookiesSupported #keycloak.js?version=6rmi9:1314 Promise.then (async) (anonymous) #keycloak.js?version=6rmi9:350
I cannot update the "keycloak.js" file as seen in some answers because it is not an adapter but the builtin file from Keycloak. I also have updated the Content Security Policy of the master realm with the following :
frame-src 'self' http://localhost:8000 http://localhost:8080 http://localhost:8081; frame-ancestors 'self' http://localhost:8000
Have I overlooked anything ?

OKTA(IdP) - Shibboleth(SP) with reverse proxy to Tomcat

I am spinning a big wheel now. please shed some light.
Reverse proxy is working with Apache. So, when I access https://hostname/app/default.html, it opens Tomcat app url. No issue.
The tomcat app currently redirects to https://hostname/app/login.html which has a login box.
1) Do I need to disable UserDatabase on Tomcat server.xml ?
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
2) Is this Shibboleth configuration correct ?
But, when I try configure this with OKTA- Shibboleth(3.0), it's looping OKTA SSO url.
In shibboleth2.xml
<ApplicationDefaults id="default"
entityID="https://hostname/shibboleth-sp"
REMOTE_USER="userid" >
<SSO entityID="http://www.okta.com/~~~~">
OKTA's metadata is downloaded and located with shibboleth2.xml file.
cert is also generated and placed in the same folder.
3) Is this OKTA configuration correct ?
In OKTA widget configuration menu,
- Single sign on url :https://hostname/Shibboleth.sso/SAML2/POST
- recipient url : https://hostname/Shibboleth.sso/SAML2/POST
- destination url :https://hostname/Shibboleth.sso/SAML2/POST
- audience restriction :https://hostname/shibboleth-sp <-- above SP entityID
- default relay state : ??
right now, when I click on the widget on OKTA, it's looping.
https://hostname/Shibboleth.sso/SAML2/POST
contains SAML response.
then, it redirects to OKTA SSO url. It never ends.
https:// xxx.oktapreview.com/app/xx_reverse_proxy_/xxxx/sso/saml?SAMLRequest=~~~&RelayState=~~~
This contains SAML request but it looks like this.
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="https://hostname/Shibboleth.sso/SAML2/POST"
Destination="https://okta sso/sso/saml"
ID="xx"
IssueInstant="2018-11-02T15:39:24Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml:Issuer
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://hostname/shibboleth-sp
</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="1"/>
Is this Issuer url correct? Why is it looping and how to fix ?
Re Q#1: You only need Tomcat users if you're going to protect an application with it, such as the Tomcat manager. Otherwise, no.
Re Q#2: You list <SSO entityID="http://www.okta.com/~~~~"> but Destination="https://okta sso/sso/saml" from the SAML. You might want to check http/https. This is a very common cause of looping. Eliminate any potential http/https inconsistency.
FWIW Issuer looks correct to me... that's what you specify in entityID="https://hostname/shibboleth-sp"

why is keycloak removing the SSL in the redirect uri?

We have a simple requirement where:
PS: https:/ === https://
When user hits https:/company_landing.company.com , they should be redirected to keycloak login page (at https:/ourcompany-keycloak.company.com). User enters his/her keycloak login credentials. Upon successful login to keycloak , they will be presented to the company_landing page.
The trouble is :
When User types - https:/company_landing.company.com
Keycloak tries to bring up the landing page but gives 500 Internal server error and says "Incorrect redirect uri" and in the browser I see this:
https:/ourcompany-keycloak.company.com/auth/realms/realm1/tokens/login?client_id=company_dev&state=aaaafffff-559d-4312-a8be-123412341234&redirect_uri=http%3A%2F%2Fcompany_landing.company.com%3A8081%2F%3Fauth_callback%3D1
If you observe the redirect uri above, I think the problem is that instead of https the redirect uri starts with http and http:/company-landing.company.com doesn't exist.
Settings:
keycloak settings: -
Realm --> settings --> login : Require SSL = all Requests (tried with "external" also)
Applications-->realm1-->settings-->Redirect URI = https://company_landing.company.com/*
AWS load balancer:
Port config: 443(https) forwarding to 8443
I am confused as to why it is stripping the SSL? The above works fine when testing on local environment(probably because its http://localhost) but this always gives an invalid redirect url when trying to access any link that is ssl encrypted.
-mm
You have to add the following property in the proxy configuration json file, (by default proxy.json) as an application attribute (same level as "adapter-config"):
"proxy-address-forwarding" : true,
This configuration attribute is not documented, however present in the sources of the proxy configuration: https://github.com/keycloak/keycloak/blob/master/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyConfig.java
You don't need a certificate to be installed or use changes in adapter config.
This needs to be done in your standalone.xml, standalone-ha or domain.xml (as the case may be) as documented in the Keycloak document reverse proxy section https://www.keycloak.org/docs/latest/server_installation/index.html#_setting-up-a-load-balancer-or-proxy
Assuming that your reverse proxy doesn’t use port 8443 for SSL you also need to configure what port HTTPS traffic is redirected to.
<subsystem xmlns="urn:jboss:domain:undertow:4.0">
...
<http-listener name="default" socket-binding="http"
proxy-address-forwarding="true" redirect-socket="proxy-https"/>
...
</subsystem>
Add the redirect-socket attribute to the http-listener element. The value should be proxy-https which points to a socket binding you also need to define.
Then add a new socket-binding element to the socket-binding-group element:
<socket-binding-group name="standard-sockets" default-interface="public"
port-offset="${jboss.socket.binding.port-offset:0}">
...
<socket-binding name="proxy-https" port="443"/>
...
</socket-binding-group>

Spring Security X.509 Preauth

I'm using Spring Security 2.x's Preauthentication with X.509 certificates.
I get the certificateText via HttpServletRequest.getAttribute("CERTIFICATE").
Sometimes, the above call returns "" (empty). I believe it occurs when the HTTP session has expired.
What would explain why HttpServletRequest.getAttribute("CERT") returns empty?
EDIT In Kerberos, for example, the ticket is available in every HTTP request. Is the cert not always in X.509 HTTP requests?
Please access to certificate using this code:
X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
Certificate is always populated to request after successful client certificate authentication.
Ensure your support long certificate chain:
Add the max_packet_size propery to the worker.properties file
worker.ajp13w.max_packet_size=65536
Add the packetSize propery to the configuration of Ajp connector in the Tomcat configuration \conf\server.xml
<Connector port="8089"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" packetSize="65536"/>
Apache logs:
http://httpd.apache.org/docs/2.2/logs.html#accesslog
http://httpd.apache.org/docs/2.2/logs.html#errorlog
http://httpd.apache.org/docs/2.2/mod/core.html#loglevel

Consuming secured WCF service through basicHTTPbinding

I am consuming an secured service hosted over basicHttpBinding
I have to pass credentials to the service for authenticatioon
Here’s the config setting for the client
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
While calling the service, I am getting following exception message
An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
Message = "An invalid security token was provided (Bad UsernameToken Values)”
I not sure how to get it working I am curious if somebody can help me out or provide me any url where I could find the solution
When you create your MyServiceClient object you can set the username and password on the clientInstance.Credentials.UserName object.