Password with a colon fails basic auth? - java

I'm using basic auth. If my password contains a colon, I seem to get a failure to authenticate. Are colons not allowed in a password? How I'm authenticating:
DefaultHttpClient client = new DefaultHttpClient();
HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {
...
};
client.addRequestInterceptor(preemptiveAuth, 0);
client.getCredentialsProvider().setCredentials(
new AuthScope("example.com", 443),
new UsernamePasswordCredentials("me", "password:test"));
Passwords without a colon always work. Passwords with a colon always fail. Do I have to escape the password somehow before handing it to the UsernamePasswordCredentials class constructor? I know basicauth uses the username/password separated by a colon, then base64 encoded, is that what the problem is here?
Thanks
---- Update ------
Thanks all, yes was a problem in the server I was communicating with!

It should work. RFC2617 is the RFC around HTTP authentication. The spec does not place any restriction on the characters used within a password, only on the username;
To receive authorization, the client sends the userid and password,
separated by a single colon (":") character, within a base64 [7]
encoded string in the credentials.
basic-credentials = base64-user-pass
base64-user-pass = <base64 [4] encoding of user-pass,
except not limited to 76 char/line>
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT

If the server has a bug in separating that Base64 "username:password", the authentication method will fail. Either check on your server (perhaps there are updates available? go with a different server?), don't use a colon in your passwords, or use a different authentication method.
Out of curiosity, what server are you trying to authenticate against?

I know this is an old post, but in case others run into the same issue:
The code in new UsernamePasswordCredentials("me", "password:test")); might split the string on every colon. Here is an example in PHP that would fail:
$bits = explode(':',$auth_string);
$user = $bits[0];
$password = $bits[1];
Here is a fix:
$bits = explode(':',$auth_string);
$user = array_shift($bits);
$password = implode(':',$bits);

Just had an issue with a colon in the password. Seems like the username and password won't be splitted correctly.
Example user:pass:word
In my case the delivered Password in PHP was just "pass" instead of "pass:word".
I've learned to avoid special chars like : (colon) and # (at) in the password. It's a bit strange, because the same logic worked correctly before we've updated to php-fpm (I don't know if this issue belongs to php-fpm).

Related

Replace + with its unicode equivalent in a url

I need to test a login process with the beta server and the security policy was updated so that all users have a unique email address.
So I thought for testing the app I would just use this type of email address
"myemailaddr+a#gmail.com"
where the +a allows for a unique address. Then on each subsequent test I would use "+B" etc to ensure I have a unique email address.
All good with the server but when I try and place the URL into my android webView it wont allow me to log in. Another genuine email address works just fine.
SO, how do I replace a "+" in a url string with its Unicode value of "%2B" and is it possible to do so in a URL.
Here is the URL template:
https://team.mycompany.com/teambeta/Login.aspx?username=myemailaddr+a#gmail.com&password=xxxxxxxx&mobile=1&offSetHours=11&appDevice=AndroidAndroid
Is what I am hoping to acheive possible or do I need to go and create multiple unique email addresses for testing?
Use URLEncoder.encode(). See the documentation at https://developer.android.com/reference/java/net/URLEncoder.html
After struggling with the URL ideas and other suggestions on the net I simply replaced all instances of "+" with "%2B" as follows.
webURL = webURLBefore.replace("+", "%2B");
Works well. And I did not have to encode it as when I did I was strunggling to encode just the "+" and the whole URL was encoded and would not work.
Hope this helps someone.

JWT signature does not match locally computed signature

I am using
JwtBuilder builder = Jwts.builder()
.setId(user.getEmail())
.signWith(signatureAlgorithm, signingKey);
to create a token then
Jwts.parser().setSigningKey(secret).parse(token);
to authenticate. When I run this in a JUnit test, it works fine. However, when I authenticate token passed as a header over REST call, authentication fails with SignatureException. I have verified the token on both ends of the HTTP call and the token string is identical. Code to create/authenticate is static, therefore, the secret is same on each side.
static Key secret = MacProvider.generateKey(); will generate a new random key each time your server is reloaded because static variables are initialized when the class is loaded
It means that if you issue a JWT, it is only valid as long as the server does not reboot. The SignatureException you got is because the signing key it is different
You need to store the signing key secret.getEncoded() after first generation and load it when your module starts
I have had the same problem, I noticed that in sources whenever they convert the signing key they explicitly specify UTF-8 encoding. I tried changing the encoding while both decoding the token:
private Jws<Claims> decodeToken(String token) {
return Jwts.parser()
.setSigningKey(securityProperties.getTokenSecret().getBytes(Charset.forName("UTF-8")))
.parseClaimsJws(token);
}
And when signing the token:
private String getSignedToken(UserDetailsAdapter user, List<String> roles, byte[] signingKey) {
return Jwts.builder()
.signWith(Keys.hmacShaKeyFor(signingKey), SignatureAlgorithm.HS512)
.setHeaderParam("typ", securityProperties.getTokenType())
.setIssuer(guiServerSecurityProperties.getTokenIssuer())
.setAudience(guiServerSecurityProperties.getTokenAudience())
.setSubject(user.getUsername())
.setExpiration(new Date(System.currentTimeMillis() + 864000000))
.claim("rol", roles)
.compact();
}
This is the only thing that fixed this for me.
I had a similar problem. In my case it was wrong token validation. I set sign as bytes:
.signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret().getBytes())
But when i was parsing the token and setting signKey i setted it as a String, not as bytes:
Jwts.parser().setSigningKey(signingKey).parseClaimsJws(this.token)
Also always check quotes and spaces when checking token, there often can be excess space/quote in the start/end of the token (use trim() method)
I had a similar problem. In my case both keys were the same, but for some reason I was receiving a token within quotes (e.g "Syasda.da3das.aDjty6" instead of just Syasda.da3das.aDjty6).
It took me quite some time to realize this since most of the time while testing on jwt.io I would just copy the token manually without the brackets to verify it.
token = token.replace("\"","");
Removing those quotes solved the problem for me. Hopefully this will help someone else as well.
I solved the problem modifying the HOST in the URL REST endpoint. It had a wrong host which was returned error HTTP 401 unauthorized.
Two types of problems meight exists:
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); generates a different random key each time the function secretKeyFor is run. So if you want to generate a constant key, try this one
public SecretKey generalKey(){
String stringKey = Global.JWT_SECRET;
byte[] encodedKey =Base64.decodeBase64(stringKey);
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length,
"HmacSHA512");
return key;
}
In my code, I recieve the token transferred by ajax, and JSON.stringify() is used to convert the javasript object to string, which wrapped additional quota on the origin string, try to eliminate the quota as Nuper said.

Camel SFTP with username with special characters

In Camel (2.15.0) call to the SFTP (docs) as such:
String uri = "sftp://foo.co.uk?username=Me+Admin&privateKeyFile=/my/id_rsa&knownHostsFile=/my/known_hosts&preferredAuthentications=publickey"
producerTemplate.sendBodyAndHeader(uri, fileContents, "CamelFileName", fullFilePath);
Results in SFTP attempt for user Me Admin. Clearly the + is replaced by a space.
I tried to url-encode this (Me%2DAdmin), still replaced by space (Me Admin).
Tried to encode it twice, now the SFTP attempt is for username Me%2DAdmin.
Anyone has an idea how do I get Camel to SFTP for a user with a + in the username? Thanks.
It’s always good to surround the username/password with RAW() tag. For example sftp:user#hostname?password=RAW(password#123)
Ok to answer my own question, changing the request url from sftp://host?username=user to sftp://user#host fixes the problem. The username still has to be encoded once:
String uri = "sftp://Me%2DAdmin#foo.co.uk?privateKeyFile=/my/id_rsa&knownHostsFile=/my/known_hosts&preferredAuthentications=publickey"
producerTemplate.sendBodyAndHeader(uri, fileContents, "CamelFileName", fullFilePath);

How to set username and password using RESTEasy client builder?

I have a url which needs authentication (like a browser pop up appears asking username and password.)
Generally, we can use the following format to achieve this:
http://username:password#url.com
Using RESTEasy client builder
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://url.com");
How to achieve it without having to construct the http://username:password#url.com myself? I've seen if there are any methods which I could use to set it with no luck. Also I'm not sure how these credentials are passed, headers, cookies etc..
Looks like Basic Authentication. If that's the case, you just need to set the Authorization header to Basic base64encode(username:password).
For example:
String credentials = "username:password"
String base64encoded = Base64.getEncoder().encodeToString(credentials.getBytes());
Response response = target.request()
.header(HttpHeaders.AUTHORIZATION, "Basic " + base64encoded)....
The Base64 class I used is from Java 8. If you're not using Java 8, there are libraries that have Base64 support. Prior to Java 8, there's a com.sun internal Base64 class, but it's advised not to use those.
If you just want to run a quick test (and don't have Java 8 or don't want to go looking for a lib), you can go to this site and just type in your username:password and encode it, then just copy and paste to your code.
For example:
base64encode(username:password) == dXNlcm5hbWU6cGFzc3dvcmQ=

javax.mail.URLName cannot parse username and password when username contains an '#' character

I am using org.springframework.integration.mail.ImapMailReceiver from spring integration to read some emails from IMAP server.
Like many other IMAP servers, the IMAP server I am connecting to uses emails addresses as usernames.
So I am creating new instance of ImapMailReceiver this way
new ImapMailReceiver(“imap://user#mail.XXXX.com.au:password#mail.XXXX.com.au:143/INBOX”);
I believe ImapMailReceiver uses URLName class to parse the given string into protocol, user and etc.
However since the url string contains 2 '#' characters, URLName class is getting confused and failing to parse the username and password.
Have anybody else had similar problems before? How did you get around this problem?
Any comments will be appretiated!!
Thanks.
The "#" in the user name needs to be URL encoded. If you use the URLName constructor that takes separate username, password, etc. parameters, it will do that for you. If you're writing it by hand, you need to write it correctly, with the proper encoding for any special characters.
I've try to get mails from GMAIL that's why I use imaps
`imapMailReceiver = new ImapMailReceiver("imaps://" + URLEncoder.encode(USERNAME, "UTF-8") + ":" + PASSWORD + "#imap.gmail.com:993/INBOX");`
No, it works well

Categories