I am current Apache Tomcat user designing an Akka HTTP based replacement for a HTTPS web service that uses client certificates for authentication and authorization. Using Tomcat I am accustomed to retrieving the client X509Certificate with a servlet request attribute
request.getAttribute("javax.servlet.request.X509Certificate")
I need the certificate for some additional authorization checks inside the handler for select routes. How would retrieve the client certificate in this way with Akka HTTP 10.0.x?
You need to enable decorating requests with TLS session info through the config settings for the server:
akka.http.server.parsing.tls-session-info-header = on
And then extract the info for a specific request using the synthetic header akka.http.scaladsl.model.headers.Tls-Session-Info like so:
headerValueByType[`Tls-Session-Info`]() { sessionInfo =>
val sslSession = sessionInfo.getSession()
sslSession.getPeerCertificates
... etc ...
Related
I have setup an NGINX Reverse Proxy; using Keycloak 18 to validate users. Moving onto the customer network, I had to change the port mapping of the NGINX-RP to 9443 from 443. Keycloak provides a bearer token upon login. The bearer token will have the iss claim url: xx.xx.xx.xx:9443. This creates an authentication error, because the the expected value is xx.xx.xx.xx. Is there any way for me to change the url authority to contain the new port number?
In the nginx you could use the X-Forwarded headers to tweak the request and update the host and port for downstream calls.
But, you could also handle all your authentication related api calls under the same port (server{} block with location{} sub blocks) and that way you don't have to make this change plus you can also preserve the integrity of the request.
We're developing a native application that accesses content on a resource server (which is also under our control). The resource server will require the user of the native app to authenticate by OpenID Connect to get an access key which is passed as a bearer token (RFC 6750). The authorization server is a separate server running Keycloak.
I'd like to avoid hard-coding information into the client software about the address of the authorization server. Instead, I'd like the resource server to provide the link to the auth server's provider discovery endpoint, possibly as part of the HTTP 401 challenge. I could just invent an X-MyApp-* header, but I was wondering if there is an established convention for this (whether an HTTP header, body content in the 401 response, a standard URL on the resource server etc)?
RFC6750 define the usage of WWW-Authenticate Response Header.
Section 3 of the spec define follow,
If the protected resource request does not include authentication
credentials or does not contain an access token that enables access
to the protected resource, the resource server MUST include the HTTP
"WWW-Authenticate" response
You may utilise this header to respond back the address of the authorization server. Specification allows to have attributes other than the ones defined by specification,
All challenges defined by this specification MUST use the auth-scheme
value "Bearer". This scheme MUST be followed by one or more
auth-param values. The auth-param attributes used or defined by this
specification are as follows. Other auth-param attributes MAY be
used as well.
Now if we can define a custom attribute named auth_server, then we can add it to 401 response's WWW-Authenticate header as below
WWW-Authenticate: Bearer realm="example", auth_server="URL-TO-OIDC-SERVER"
Your client must parse the header and extract the auth_server value .
After the user requests a protected resource X the server responds
with code 401.
The browser prompts the user to inser user-name and
password and automatically re-send the request to the server with
those authentication information
My question is : is this process repeated over and over for each protected resource ?
Look at RFC 2617. There is stated for basic-athentication :
Upon receipt of an unauthorized request for a URI within the
protection space, the origin server MAY respond with a challenge ...
and also
A client SHOULD assume that all paths at or deeper than the depth of
the last symbolic element in the path field of the Request-URI also
are within the protection space specified by the Basic realm value of
the current challenge. A client MAY preemptively send the
corresponding Authorization header with requests for resources in
that space without receipt of another challenge from the server.
Similarly, when a client sends a request to a proxy, it may reuse a
userid and password in the Proxy-Authorization header field without
receiving another challenge from the proxy server.
So, from the server side this may occur at any request the the server deems unauthenticated. If resource Y does not share the prefix that had been yuthenticated with resource X then the server will re-request authentication.
For avoiding this the authentication scheme e.g. could request authentication for a common prefix of the related resources , such that authentication for prefix of resource X also covers resource Y as a prefix. This will allow the client to send the authentication header and cause the server to detect the call as already being authenticated.
Once the user input the password, the browser will remember it.
each time the client request the resource at the same website, the browser will send the authentication header automatically.
I am working on ATG which is an oracle product. The question I have is that if I receive a HTTPRequest from client(browser). The j2EE server forwards the request to ATG which creates a custom dynamohttpRequest. At this stage i want to change context and call the server again. I cant do it with the dynamoHttpRequest.
So I am planning to generate a new request or forward the request to a service as httpRequest. How can I generate a new request or forward the request to the same server from a servlet. How would that impact session for the client. Will Request forwarding impact the client session.
Not sure why you cant do with DynamoHttpRequest, but you can add your own Servlet in the RequestHandlingPipeline (/atg/dynamo/servlet/dafpipeline/DynamoHandler)
check this out : https://docs.oracle.com/cd/E23095_01/Platform.93/ATGProgGuide/html/s0807customizingarequesthandlingpipel01.html
I want to route SOAP messages to different servers depending on the message content.
I tried the Application Request Routing (ARR), but it seems, that you can only route by server variables and the HTTP header.
I found this tutorial:
Developing a Custom Rewrite Provider for URL Rewrite Module
My Question is, can I route depending on the HTTP body with a custom ReplaceProvider (IRewriteProvider, IProviderDescriptor)?
This is not possible!
Application Request Routing (ARR) can only access information from the http header.