I have a Spring-Boot application with MongoDB. I want to register the client using OAuth2.0 strategy and store client-id and client secret key in database. I am able to generate the access token by using some dummy client and secret key from the below url: http://websystique.com/spring-security/secure-spring-rest-api-using-oauth2/
I want to know how to generate the client id and secret key in my java code. Any help is appreciated.
Client ID and secret are generated by service providers to let the developers register their application and access their API's.
There are many ways of generating Client_id and Client secret.It depends on your choice.
Client_id is a public identifier for apps.It should be unique and not easily guessable . So you could use like a 32-character hex string , Guid , Guid + systemTime ,also you can hash it , encrypt it or anything else you want to make it unique identifier. (you would find java code easily for the same)
Client_secret is a secret known only to the application and the
authorization server.So you could use a cryptographically-secure library to generate a 256-bit value and converting it to a hexadecimal representation.
You should avoid using common UUID libraries.
Also you should not store the secret in plain text, instead only store an encrypted or hashed version, to help reduce the likelihood of the secret leaking.
Here are some examples of client ID from services that support Oauth:
Foursquare: ZYDPLLBWSK3MVQJSIYRF1OR2JXCY0X2C5UJ2QAR2MAAIT5Q
Github: 6779ef20e75817b79602
Google: 292085223830.apps.googleusercontent.com
Instagram: f2a1ed52710d4533bde25be6da03b6e3
Related
In Payment Intent API (https://stripe.com/docs/api/payment_intents/object) ,
Many of the places it is written "RETRIEVABLE WITH PUBLISHABLE KEY" fo ex- id, currency, payment_method, what does it mean?
Whether it means that we can retrieve these value when we integrating the client SDK?
The publishable key is used in your client-side code
https://stripe.com/docs/keys#:~:text=On%20the%20client%2Dside.%20Can%20be%20publicly%2Daccessible%20in%20your%20web%20or%20mobile%20app%E2%80%99s%20client%2Dside%20code
So yes, when using Stripe SDK on your client-side using the publishable key (pk_xxx) you can retrieve only the fields that mention “retrievable with publishable key” in the doc.
If you use your secret key (sk_xxx) to retrieve a PaymentIntent, you will get access to all its properties.
Also, if you want to create a PaymentIntent you must use the secret key in your backend.
Small question regarding a Spring Boot 2.4.2 app, where I need to retrieve a password stored inside Vault, containing special/Chinese character please.
Setup:
A Hashicorp Vault instance which is storing our passwords. So far so good, for most of the passwords, it is storing them safely, and we can retrieve them, very happy.
Once the password is retrieved by the app, it is used to make an http request to some third party API. The third party API gives us the password via other channel and we store it inside Vault (question is not here)
We retrieve the password via this way, with the Spring Vault library.
#Value("${password.from.vault}")
private String passwordFromVault;
And use it this way to make the http call
webClient.mutate().baseUrl("https://third-party").build().get().uri("/uri").header("X-the-password", passwordFromVault ).[...]
When the password inside Vault is plain English letter, this is working fine.
Now, for some of the passwords we see them with special Chinese character
$ vault kv get secret/creds
====== Data ======
Key Value
--- -----
password.from.vault password-新年快乐-password
Unfortunately, this seems to cause issues.
The API call started to fail, and after a quick debug session, the third party assured us they see this from their logs
X-the-password: password-????-password
Basically claiming, we are not sending the correct password (the one with special/Chinese character)
I have tried this thinking it was an encoding issue, but not working neither
final String pleaseHelp = new String(passwordFromVault.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
webClient.mutate().baseUrl("https://third-party").build().get().uri("/uri").header("X-the-password", pleaseHelp ).[...]
Question, How can I retrieve and send the request so the third party API gets the correct password containing special characters please?
Thank you
If those escaped ascii characters (for instance 新年快乐), if they are inserted from the web UI, are automatically inserted as 新年快乐.
In order to get them at run time, they should be inserted with the vault cli, as \u5317\u4eac for instance
I recently got to know about Json Web Token (JWT). Since I liked how it works I have started to implement it on my project. My project involves two apps to communicate. One is an android app and the other is Laravel web application.
The mobile app logs in after the user credential is authenticated from the server side.
I have sent the username and password to server from the mobile app and I have got the JWT in string format. But from this point onward I couldn't find a way to collect the JWT content.
I have gone through almost all possible shown (googled results) but I couldn't manage to get the contents, signature and header.
One of the method I have got a little bit further with, was using the following code, notice I have removed the setSigningKey():
try {
Claims claims = Jwts.parser().parseClaimsJwt(jwtHeaderAndClaim).getBody();
System.out.println("ID of the claims: " + claims.getId().toString());
}catch (Exception e){
Log.e("Exception: ", e.toString());
}
The above code generates the following error:
Exception: io.jsonwebtoken.PrematureJwtException: JWT must not be accepted before 2016-06-14T10:20:09+0300. Current time: 2016-06-14T10:19:37+0300´
the jwtHeaderAndClaim is the JWT String after removing the signature part only (i.e: "xxxxxx.yyyyyyyy."). if i put the jwtString (xxxxxxx.yyyyyyyy.ccccccc) instead of jwtHeaderAndClaim the following error will occur:
Exception: io.jsonwebtoken.UnsupportedJwtException: Signed JWSs are not supported
If I put the setSigningKey as shown in stormpath example:
Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret())).parseClaimsJwt(jwtString).getBody();.
The above code will not work for two reasons:
1. I don't have the library
import javax.xml.bind.DatatypeConverter;
2. I don't know how to get the key.
But know that I don't need the key since this time I am trying to login and collect the user information's (like firstname, lastname, phone, etc), and the signature (token) so that the next time I send data to be stored to the server side I have the token to get access to the backend.
Can anyone please help me?
You have many questions. I try to answer some of them
io.jsonwebtoken.PrematureJwtException: JWT must not be accepted before
2016-06-14T10:20:09+0300. Current time: 2016-06-14T10:19:37+0300´
You are using nbf (not before) attribute in JWT. Do not use it (it is optional) or sets a range of validity given that the clocks of the devices will not be synchronized
From RFC 7519
The "nbf" (not before) claim identifies the time before which the JWT
MUST NOT be accepted for processing. The processing of the "nbf" claim requires that the current date/time MUST be after or equal to the not-before date/time listed in the "nbf" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL.
Signed JWS
Exception: io.jsonwebtoken.UnsupportedJwtException: Signed JWSs are
not supported
Do you want to validate the signing key at client side or at server side?
If you use the JWT for authentication replacing user & password, and you are sending token in each request, you can validate the signature at server side.
If you want to validate the key on the app, do not use a symmetric key, because it could be a big vulnerability if it fell into the wrong hands. See. You can use and asymmetric key pair. Sign the JWT in server with the private key and validate on device with public key.
I don't have the library import javax.xml.bind.DatatypeConverter
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
byte[] data = Base64.decode(base64, Base64.DEFAULT);
I don't know how to get the key.
Your key probably was generated on server side in this way
Key key = MacProvider.generateKey(SignatureAlgorithm.HS256);
byte data[] = key.getEncoded();
Make available the key data[] to client in the way you prefer. Using assymetric keys, you only need to make available the public key.
KeyPair keyPair = RsaProvider.generateKeyPair();
byte data[] = keyPair.getPublic().getEncoded();
I am a new guy to Spring OAuth 2.0. We would like to use the "Client credentials" grant type for our resource server .While implementing this type we are not sure about the maintaining the "Client ID" and "Client Secret" as plain text in the databases. Somebody will hack these client ID and client secret and may miss use these if we store client secret as plain text.
Can any one please let us know whether is there any way to keep these values "Client ID" and "Client Secret" in the encrypted format?.
Is there any default option available in Spring OAuth 2.0 to encode and decode it?
Please let usknow is there any specific reason to store the client secret as plain text?
Thanks,
You MUST NOT save the client secret as a plain text.
The client secret MUST NOT be decryptable.
Just use org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder and it will encrypt client secret using BCrypt algorithm.
I am using the Java class org.apache.hadoop.security.
authentication.server.AuthenticationFilter from Apache
Hadoop 2.5.0 as a filter in front of a Tomcat 6 Servlet we
wish to add Kerberos authentication to.
I am attempting to write some test cases against this filter
so that we have a better understanding of how it
works and what it does.
In order for the filter to authenticate a user, it is reading the
'Authorization' header of the HTTP request,
expecting the value to contain 'Negotiate '
My understanding of how Kerberos works leads me to believe that I
should be able to write code while creating my
HTTP request that looks something like this:
// normally the server principal keytab is not available from the client side,
// but for the purpose of making test cases I see no problem with sharing the keytab
// between the client side and the server side
javax.security.auth.kerberos.Keytab kt = KeyTab.getInstance("keytab");
KerberosKey keys[] = kt.getKeys("HTTP/voltage-pp-0000.albert.int#ALBERTS.INT");
SomeTokenType token = new SomeTokenType();
<code to set token parameters>
// my understanding of Kerberos is that the only cyphertext key
// needed on this token
// is one of the server principal's keys from the Keytab file
// (which does contain ~5
// keys of different sizes and types, I've checked)
EncryptedTokenType etoken = <encrypt token with a key from keys>
byte[] array = etoken.getBytes();
httprequest.addHeader("Authorization","Negotiate " + new Base64(0).encode(array));
So, questions here:
What is the Java Class that embodies the Kerberos Auth Token sent
in "Authorization Negotiate"?
What fields of that auth token have to be set to what values?
What is the encryption algorithm used to encrypt the auth token
against the keytab key?
What is the best keytab key to use?
What is the mechanism for byte-serializing the auth token, once
encrypted?
You are correct in that it is possible to "forge" a ticket in this manner. However, I know of no standard kerberos API that would do this.
You'll essentially need to reverse engineer the entire kerberos protocol to
create a service ticket based on the keytab. The service ticket format is
documented here
https://www.ietf.org/rfc/rfc4120.txt
You can use any of the keys in the keytab to encyrpt the service ticket. Once
you have the service ticket, you'll need to implement this RFC to create the
negotiation header.
https://www.rfc-editor.org/rfc/rfc4559
Generally, it's a lot simpler to just get a keytab for a client principal and use that and kinit to get a service ticket for testing. Your approach could work
and there is probably hacker code out there somewhere to implement it, but it's
an extremely non-standard way to do testing in a kerberos environment.