I'm using SAML tokens to authenticate against a set of REST-ful services, by putting the SAML token in the Authorization header.
I can't find anything out there that would suggest that there's a standard way to do this. For example, do I use:
Authorization: Bearer <EncryptedAssertion ...
or:
Authorization: Bearer PEVuY3J5cHRlZEFzc2VydGlvbiAuLi4=
or:
Authorization: SAML PEVuY3J5cHRlZEFzc2VydGlvbiAuLi4=
or something else?
Note that the first one doesn't work if the certificate has multiple name components (because the comma messes up the header parsing).
The fact that I'm using 'Bearer' doesn't say anything about the format of the token.
Apache CXF appears to use the third variant.
Which one is standard? Is there a standard? If not, is there a de-facto standard?
The standard for custom auth schemes in HTTP is defined in the RFCs 2617 and 7235.
Authorization: scheme key="value", ...
I doubt there is a standard for your specific case, but I'd say this is acceptable:
Authorization: SAML bearer="PEVuY3J5cHRlZEFzc2VydGlvbiAuLi4="
After doing quite a lot of research on this topic, I could not find any standard defining how to use a SAML Token in the Authorization header.
However CXF which is a quite famous Web-Serviec stack supports SAML Token in the following manner:
Authorization: SAML eJydV1m....9fYTCPr=
OAuth2 also defines how to authenticate with SAML Token to receive a OAuth2 Access Token which can then be used to invoke another REST Service (https://www.rfc-editor.org/rfc/rfc7522)
POST /token.oauth2 HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2-bearer&
assertion=PHNhbWxwOl...[omitted for brevity]...ZT4
Related
I've seen both Authorization: Bearer <token> and Authorization: JWT <token> when making HTTP requests using the Authorization header. What is the difference between Bearer and JWT?
As far as I know, there isn't really much of a difference between the two, or any other schema you might come across being used in the header.
Authorization: Bearer <token> is just a standard way of passing around JWT tokens between the client and the server.
if you've written server-side code, you'll notice that you're the one placing the logic to split and extract the token from the header.
So, if you're designing both the server and the client, you can send in any key-value pair you wish to, just that they should match both sides.
You can see JWT docs for more information. They mention using the Bearer schema as a standard way.
I'm currently trying to retrieve a user token from the keycloak token endpoint using a POST request (instead of using one of the designated adapters). I have set up a keycloak realm and added my own machine as a client. In the documentation the Token Endpoint is described as:
/realms/{realm-name}/protocol/openid-connect/token
As far as I have read in the openid specification, I will need to set the body parameter grant_type=authorization_code as well as the parameters code and redirect_uri. I will also need to set the Authorization header, for which I will need a Basic Token.
So far I will get the response:
"error": "unauthorized_client", "error_description":
"INVALID_CREDENTIALS: Invalid client credentials"
Where do I get the Basic Authorization Token from? I expected that I need to provide a username and a password, since the JWT token is what I'm trying to recieve as response. Do I need to set the redirect_url if I just want to request a token?
Keycloak offers more than one way to retrieve a user access token, following the OpenId Connect spec. Here you have the steps to do it for Authorization code flow (the one recommended for web applications) according to the openid connect spec: https://rograce.github.io/openid-connect-documentation/explore_auth_code_flow
Basically, if you're not using any adapter, when detecting a request to some protected resource you should:
Perform a redirection to the keycloak login page (keep in mind keycloak uses the REALM entity, so you'll need to specify it too):
HTTP/1.1 302 Found
Location: https://mykeycloakinstance.org/auth/realms/demo/protocol/openid-connect/auth?
response_type=code
&scope=openid
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
You'll need to keep the state value in the client, as it needs to survive the redirection process:
It is recommended that client’s use this parameter to maintain state
between the request and the callback. Typically, Cross-Site Request
Forgery (CSRF, XSRF) mitigation is done by cryptographically binding
the value of this parameter with a browser cookie.
You don't interact with username/passwords. The keycloak authentication page does. Once the login is successful, it will redirect to your page with a valid code:
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
Here you'll need to either check that the state is the one you originally sent (you may need to track it through web session, using cookies) and also to obtain the token using that code. You do a POST to the authorization endpoint with this code:
POST /auth/realms/demo/protocol/openid-connect/auth HTTP/1.1
Host: https://mykeycloakinstance.org
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
This is the flow in summary, I haven't tested the code myself, so use it as an example and don't hesitate to fix it if you consider ;-)
See also:
What are Keycloak's OAuth2 / OpenID Connect endpoints?
My sectoken is authorized but I don't know how to formulate a URL so that I can bypass the WSO2 IS sign-in page (login.do).
I read online it can be passed through a link in this format:
localhost:9443/samlsso?SAMLRequest=[SAMLRequest]§oken=[SECTOKEN]
I'm just not sure what to put in for [SAMLRequest].
As for the answer, you may try to use OneLogin PHP module to generate a SAML Request.
Here is an example SAML Authn Request however you may need to change the issuer, destination, AssertionConsumerURL, and issue timestamp.
Please note there's difference when sending SAML Request as GET and POST. GET (Redirect-Binding) uses deflate and encode, signature is a separate request parameter, POST (POST-Binding) uses signed XML and only encoded XML, not deflated.
SAML is great protocol (very well designed and secure when implemented properly), but it may look difficult for people who hasn't use it before, it may require using external libraries to properly create requests and validate responses. That's why you may be as well looking for option which would may make your life simpler, such as using WSO2IS for SSO (single-sign-on) e.g. using simpleSAMLphp or direct OAuth authorization request.
Is there a standard HTTP Authentication scheme which is appropriate to use with OpenID Connect? The scenario I have in mind is as follows:
An HTTP Service requires authentication of users. One of the possible authentication methods is to use a federated identity from a 3rd party OpenID Provider. The Service is registered with the 3rd party OpenID Provider as a confidential client, and possesses a client_id and a client secret.
When a user tries to access the HTTP Service, the server responds with a 401 Unauthorized and a WWW-Authenticate header containing information about how to initiate an authentication request with the OpenID Provider:
WWW-Authenticate: OpenIDConnect realm="MyService", client_id="1234-5678", authorization_url="https://provider/authorize"
The client contacts the authorization endpoint, authenticates, and then obtains an authorization code. The code is then specified in a subsequent request to the Service via the Authorization header, e.g.:
GET / HTTP/1.1
Authorization: OpenIDConnect client_id="1234-5678", code="AAABAAA..."
The Service will use the code to obtain an ID Token from the OpenID Provider and establish an authenticated session with the client, e.g. by setting a cookie or returning a new set of credentials to use for subsequent requests.
The OpenIDConnect scheme is something I made up for this example. I have tried searching for a standard way to do something similar, and the absence of results has left me with the following possible answers:
I have not searched hard enough.
What I am trying to do is misguided and wrong.
Everybody implements their own custom authentication schemes for this purpose
I think you did not know where to look for in the first place. Since RFC 7353, authentication schemes in HTTP are subject to the IANA HTTP Authentication Scheme Registry. In said registry, you are going to find the OAuth scheme which is subject to RFC 5849, section 3.5.1 and is looking a lot like what you are looking for. That being said, however, this is for OAuth 1.0. OAUth 2.0 is resorting to the Basic (RFC 6749) and Bearer (RFC 6750) schemes.
This in its entirety is concernig authorization (via OAuth). OpenID's realm is authentication, though. You may want to look at What's the difference between OpenID and OAuth?
Should I used custom HTTP Header to pass JSON web token or HTTP Authorization header in my RESTFul services.
I have already read Custom HTTP Authorization Header but could not understand clearly drawback, if I use header like - X-ABC-Token.
After reading REST Authorization: Username/Password in Authorization Header vs JSON body, I feel Authorization seems good choice.
If I use HTTP Authorization then I believe I can use scheme bearer to achieve this as mentioned in
rfc6750
Please suggest me what are the best ways to pass this token in each HTTP request.
You shouldn't expand the standard features of the protocol if the existent ones solve your problem. The correct approach is to define your own authorization scheme for the Authorization header.
You can do something like:
Authorization: MyCompanyLogin token="abcdefg...."
Browsers and proxies already know about the Authorization header. For example, responses to requests with an Authorization header are not cached or are cached just for one user.
In contrast, browsers and proxies don't know about your custom X-ABC-Token header. A proxy may return the same page to different users, even if that header is different. This makes it possible that one user sees the information of another user. This in turn can be disabled by using the header Cache-Control: private.