I'm creating an application in Java and using jGit. As part of this I need to authenticate an user. I want to output if the user is existing or not. Currently I get an exception as user is not authorized. Below is my code.
import java.io.File;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
public class AuthenticateanUser {
public static void main(String[] args) throws Exception {
final String REMOTE_URL = "https://myRepo.git";
// prepare a new folder for the cloned repository
File localPath = File.createTempFile("TestGitRepository", "");
localPath.delete();
// then clone
try (Git result = Git.cloneRepository().setURI(REMOTE_URL)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider("myId", "myPwd"))
.setDirectory(localPath).call()) {
System.out.println("Having repository: " + result.status());
}
}
}
when I run my above code, If I give correct credentials, I get the output as
Having repository:XXXXX
if I give wrong credentials I get error as
Exception in thread "main" org.eclipse.jgit.api.errors.TransportException: https://myRepo.git: not authorized
Instead of this I want to print, Invalid credentials.
please let me know where am I going wrong and how can I fix this.
Thanks
You go:
try (Git result = Git.cloneRepository().setURI(REMOTE_URL) {
...
} catch (TransportException te) {
System.out.println("Invalid credentials");
}
for example.
You should not tell the user if the account exists or not. As in: if you tell that an attacker, he can conclude that he already got a valid username.
Related
This might sound silly but I am encountering this behavior. I am using JNDI for LDAP authentication. I have a demo program setup, where the authentication fails upon providing incorrect credentials, but the same seems to go through in a Spring controller method(I'm making a post call from a react app).
Plain Java implementation
import java.util.Properties;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
public class Demo {
public static void main(String[] args) {
Properties environment = new Properties();
String userDomain = "#region.company.net";
environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL, "ldap://region.company.net:3268");
environment.setProperty(DirContext.SECURITY_AUTHENTICATION, "simple");
environment.setProperty(DirContext.SECURITY_PRINCIPAL, "userId"+userDomain);
environment.setProperty(DirContext.SECURITY_CREDENTIALS, "wrongPassword");
try {
DirContext context = new InitialDirContext(environment);
System.out.println("Authentication Successful !!!\n\n");
} catch (NamingException e) {
System.out.println("Authentication Failed !!!\n\n");
e.printStackTrace();
}
}
}
Controller implementation
#PostMapping("/authenticateUser")
public String authenticateUser(#RequestBody HashMap<String, String> user) {
Properties environment = new Properties();
String userDomain = "#region.company.net";
environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL, "ldap://region.company.net:3268");
environment.setProperty(DirContext.SECURITY_AUTHENTICATION, "simple");
// environment.setProperty(DirContext.SECURITY_PRINCIPAL, "userId"+userDomain);
environment.setProperty(DirContext.SECURITY_CREDENTIALS, "wrongPassword");
try {
DirContext context = new InitialDirContext(environment);
System.out.println("Authentication Successful !!!\n\n");
} catch (NamingException e) {
System.out.println("Authentication Failed !!!\n\n");
e.printStackTrace();
}
return "Method executed successfully";
}
After providing incorrect password, if I execute this code then it prints Authentication Failed !!! which is expected, but when I insert this same code in a controller's method, it prints Authentication Successful !!!.
Shouldn't both behave in the same way? I find this behavior pretty weird. Perhaps, I am overlooking something?
EDIT 1 : START
It appears the line that sets the SECURITY_PRINCIPAL was commented out in case of the Spring Controller. I have commented out that part of code.
This now gives rise to another question as to why it never threw any exception ?
Not sure if I should ask this in a separate post.
Is it a proper way to authenticate by passing Username(like abc#xyz.com) as SECURRITY_PRINCIPAL or one should pass the entry path ?
EDIT 1 : END
I went through the following doc center and tried to create my own URI schema myDocs:
https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
Following is my Java program. It takes a command line argument and returns the URL in the browser.
import java.awt.Desktop;
import java.io.IOException;
public class URIOpen {
public static void main(String args[]) {
if (args.length == 0) {
return;
}
String uri = args[0];
try {
Desktop.getDesktop().browse(java.net.URI.create(uri));
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
I updated the (Default) value field of the command key like below.
"C:\Program Files (x86)\Java\jdk1.8.0_102\bin\java" -cp "C:\Users\Krishna\Documents\Study\Miscellaneous\examples" "URIOpen" "%1"
When I try to run the command myDocs:http://google.com, I end up opening infinite command prompts.
The following is my URI schema entry structure in the registry. Any help on this?
Your solution end up opening infinite command prompts because of:
you registered the execution of the custom URIOpen class to be activated by the system when it has to deal with myDocs:'s scheme based URI;
when custom URIOpen class executes the line Desktop.getDesktop().browse(java.net.URI.create(uri)); the system will receive again an URI based on the same scheme ( myDocs: ) and it will activate again a new command to execute your class again and again and again ...
Probably you would like to change your code in someway like that:
try {
java.net.URI theURI = java.net.URI.create(uri);
// System.out.println(theURI.getScheme()); => myDocs
String uriBrowsablePart = theURI.getRawSchemeSpecificPart();
// System.out.println(uriBrowsablePart); => http://google.com
Desktop.getDesktop().browse(java.net.URI.create(uriBrowsablePart));
// the above statement will open default browser on http://google.com
} catch (IOException e) {
System.out.println(e.getMessage());
}
try replacing your try-catch block with my suggestion and see if it works as required.
I have a problem with decrypting a PDF document with Apache PdfBox (v1.8.2) lib. Encryption works, but decryption with the same password throws an exception. (Java 1.6)
package com.test;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
public class PdfEncDecTest {
static String pdfPath = "G:\\files\\filed5b3.pdf";
public final static String PDF_OWNER_PASSWORD = "cd1j";
public final static String PDF_USER_PASSWORD = "";
public static void main(String[] args) throws Exception {
PDDocument document = PDDocument.load(pdfPath);
AccessPermission ap = new AccessPermission();
ap.setCanPrint(true);
ap.setCanExtractContent(false);
ap.setCanExtractForAccessibility(false);
StandardProtectionPolicy spp = new StandardProtectionPolicy(PDF_OWNER_PASSWORD, PDF_USER_PASSWORD, ap);
document.protect(spp);
document.save(pdfPath+".pdf");
document.close();
PDDocument doc = PDDocument.load(pdfPath+".pdf");
if(doc.isEncrypted()) {
StandardDecryptionMaterial sdm = new StandardDecryptionMaterial(PDF_OWNER_PASSWORD);
doc.openProtection(sdm); // org.apache.pdfbox.exceptions.CryptographyException: Error: The supplied password does not match either the owner or user password in the document.
doc.decrypt(PDF_OWNER_PASSWORD); // the same like above
}
doc.close();
}
}
I don't know what is wrong. With version 1.8.7 I get the same exception. I've posted the full code above.
Exception in thread "main" org.apache.pdfbox.exceptions.CryptographyException: Error: The supplied password does not match either the owner or user password in the document.
at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.prepareForDecryption(StandardSecurityHandler.java:265)
at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.decryptDocument(StandardSecurityHandler.java:156)
at org.apache.pdfbox.pdmodel.PDDocument.openProtection(PDDocument.java:1595)
at org.apache.pdfbox.pdmodel.PDDocument.decrypt(PDDocument.java:942)
at com.test.PdfEncDecTest.main(PdfEncDecTest.java:29)
I've put sample project to github: https://github.com/marioosh-net/pdfbox
You need the user password.
if (doc.isEncrypted())
{
StandardDecryptionMaterial sdm = new StandardDecryptionMaterial(PDF_USER_PASSWORD);
doc.openProtection(sdm);
// don't call decrypt() here
}
this works even if the user password is not null. The user password is for what the ordinary human thinks encryption is, the owner password is an encryption for the security rights.
edit: sorry, my answer is wrong, although it was helpful. You can open a PDF with the user password (you'll possibly get restricted rights) or with the owner password (you'll get full rights). What may have happened is that there is a bug with matching the owner password with 40bit keys (which is the
default). This bug is currently being investigated, see PDFBOX-2456 and search for "MD5".
I have tested your code and it work's fine for me.
i am using
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>1.8.7</version>
</dependency>
I'm trying to crawl a GitHub Wiki with JGit.
When I try it with one URL, it worked perfectly fine. Then I tried it with another random URL and got an error.
Please see the extract of my code:
import java.io.File;
import java.io.IOException;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
public class Main {
// with this URL I get an error
String url = "https://github.com/radiant/radiant.wiki.git";
// this URL works
// String url = "https://github.com/WardCunningham/Smallest-Federated-Wiki.wiki.git";
public static void main(String[] args) {
Main m = new Main();
m.jgitTest();
System.out.println("Done!");
}
public void jgitTest() {
try {
File localPath = File.createTempFile("TestGitRepository", "");
localPath.delete();
Git.cloneRepository().setURI(url).setDirectory(localPath).call();
} catch (IOException | GitAPIException e) {
System.err.println("excepton: " + e.getMessage());
e.printStackTrace();
}
}
}
This is the stack trace:
Exception in thread "main" org.eclipse.jgit.dircache.InvalidPathException: Invalid path (contains separator ':'): How-To:-Create-an-Extension.textile
at org.eclipse.jgit.dircache.DirCacheCheckout.checkValidPathSegment(DirCacheCheckout.java:1243)
at org.eclipse.jgit.dircache.DirCacheCheckout.checkValidPathSegment(DirCacheCheckout.java:1225)
at org.eclipse.jgit.dircache.DirCacheCheckout.checkValidPath(DirCacheCheckout.java:1185)
at org.eclipse.jgit.dircache.DirCacheCheckout.processEntry(DirCacheCheckout.java:311)
at org.eclipse.jgit.dircache.DirCacheCheckout.prescanOneTree(DirCacheCheckout.java:290)
at org.eclipse.jgit.dircache.DirCacheCheckout.doCheckout(DirCacheCheckout.java:408)
at org.eclipse.jgit.dircache.DirCacheCheckout.checkout(DirCacheCheckout.java:393)
at org.eclipse.jgit.api.CloneCommand.checkout(CloneCommand.java:236)
at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:127)
at Main.jgitTest(Main.java:21)
at Main.main(Main.java:13)
If you visit the wiki page of the URL that doesn't work (https://github.com/radiant/radiant/wiki), you will find this page: How To: Create an Extension.
The title of this page is the cause of the error: Invalid path (contains separator ':'): How-To:-Create-an-Extension.textile.
I assume I need to escape all output.
I suppose you are on windows. You can't create a file on windows having the ":" in the name. JGit should handle it somehow, so I suppose this is a bug in JGit.
I had the same problem with pure git, and this answer helped me:
git config core.protectNTFS false
I stole this code to test about emailing using java. Javamail is required, obviously. For some reason, I can't get javax.mail to implement. I downloaded the most recent javamail and put them in the jdk and jre lib folders, yet nothing changes. Please and thank you!
//A class which uses this file to send an email :
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* Simple demonstration of using the javax.mail API.
*
* Run from the command line. Please edit the implementation
* to use correct email addresses and host name.
*/
public final class Emailer {
public static void main( String... aArguments ){
Emailer emailer = new Emailer();
//the domains of these email addresses should be valid,
//or the example will fail:
emailer.sendEmail(
"sean_chili#yahoo.com", "clevelanm#sou.edu",
"Testing 1-2-3", "blah blah blah"
);
}
/**
* Send a single email.
*/
public void sendEmail(
String aFromEmailAddr, String aToEmailAddr,
String aSubject, String aBody
){
//Here, no Authenticator argument is used (it is null).
//Authenticators are used to prompt the user for user
//name and password.
Session session = Session.getDefaultInstance( fMailServerConfig, null );
MimeMessage message = new MimeMessage( session );
try {
//the "from" address may be set in code, or set in the
//config file under "mail.from" ; here, the latter style is used
//message.setFrom( new InternetAddress(aFromEmailAddr) );
message.addRecipient(
Message.RecipientType.TO, new InternetAddress(aToEmailAddr)
);
message.setSubject( aSubject );
message.setText( aBody );
Transport.send( message );
}
catch (MessagingException ex){
System.err.println("Cannot send email. " + ex);
}
}
/**
* Allows the config to be refreshed at runtime, instead of
* requiring a restart.
*/
public static void refreshConfig() {
fMailServerConfig.clear();
fetchConfig();
}
// PRIVATE //
private static Properties fMailServerConfig = new Properties();
static {
fetchConfig();
}
/**
* Open a specific text file containing mail server
* parameters, and populate a corresponding Properties object.
*/
private static void fetchConfig() {
InputStream input = null;
try {
//If possible, one should try to avoid hard-coding a path in this
//manner; in a web application, one should place such a file in
//WEB-INF, and access it using ServletContext.getResourceAsStream.
//Another alternative is Class.getResourceAsStream.
//This file contains the javax.mail config properties mentioned above.
input = new FileInputStream( "C:\\Temp\\MyMailServer.txt" );
fMailServerConfig.load( input );
}
catch ( IOException ex ){
System.err.println("Cannot open and load mail server properties file.");
}
finally {
try {
if ( input != null ) input.close();
}
catch ( IOException ex ){
System.err.println( "Cannot close mail server properties file." );
}
}
}
}
Just for completeness, here's the answer.
Your Eclipse is telling you
<Some Class> cannot be resolved to a type
This is usually an indication that your classpath is not correct. You said
I downloaded the most recent javamail and put them in the jdk and jre
lib folders, yet nothing changes
Don't do this. Take the javamail.jar and use it on your application Build Path. To do so, drag and drop the jar into your project, right-click it and select Build Path > Add to build path.