Giter Club home page Giter Club logo

authentication-flows's Introduction

Authentication-Flows Build Status Maven Central

The Authentication-Flows JAR implements all authentication flows:

  • create account,
  • forgot password,
  • change password by user request,
  • force change password if password is expired,
  • locks the accont after pre-configured login failures.

It's own README explains in detail all required configurations, API and more.

The authentication-flows JAR uses cryptography in order to encrypt the data in the links that are sent to the user's email, upon user's registration and "forget password" flows. Read more about the encryption module here.

This project was an oAuth2 POC, consists of all 3 oAuth parties. oAuth POC is now here: https://github.com/OhadR/oAuth2-sample

23-02-2016: Spring Versions Updated

On 23-02-2016, we have updated Spring versions to the newest!

  • Spring Security: 4.0.3.RELEASE
  • Spring: 4.2.4.RELEASE
  • Spring Security oAuth: 2.0.9.RELEASE

In addition, we have changed the build tool from Maven to Gradle. If you wish to use the older version, i.e. Maven and older Spring versions (3.1.X, oAuth 1.0.5), you can find it on a separated branch. The version in that branch is 1.6.2-SNAPSHOT (you can find in Maven Central the latest release, 1.6.2). The version on Master is 2.0.0-SNAPSHOT.

Other Project Components

JAR: common-crypto Maven Central

Both oAuth identity-provider and the authentication-flows JAR use cryptography in order to encrypt the data:

  • oAuth encrypts the access-token
  • authentication-flows encrypts the user's password,
  • authentication-flows encrypts the links that are sent to the user's email, upon user's registration and "forget password" flows.

The utility JAR, called "common-crypto", makes life easier. You can find it in this project, and it is available in Maven Central Repository as well.

See its own README.

JAR: auth-common Maven Central

common code for authentication. You can find it also in this project, and also it is available in Maven repository:

<dependency>
  <groupId>com.ohadr</groupId>
  <artifactId>auth-common</artifactId>
  <version>2.1-RELEASE</version>
</dependency>

Note the version - make sure you use the latest.

KeyStore things to know:

  1. a keystore shall be created, both for SSL and for signing the tokens.
  2. its alias and password should be updated in the prop file as well as in the tomcat's server.xml
  3. algorithm should be DSA (because in the access-token signature my code expects it to be "SHA1withDSA"
  4. if you want to work with "localhost", you should make the name "localhost":
  5. http://stackoverflow.com/questions/6908948/java-sun-security-provider-certpath-suncertpathbuilderexception-unable-to-find/12146838#12146838

creating a token using Java's keytool: keytool.exe -genkeypair -alias -keypass -keyalg DSA -keystore -storepass -storetype JCEKS -v

for example: C:\Dev\Tools>"%JAVA_HOME%\bin\keytool.exe" -genkeypair -alias alias -keypass kspass -keystore ohad.ks -storepass kspass -keyalg DSA -storetype JCEKS -v

Note that your servlet container will have to be adapted to use this keysotre (for https use). For example, if you used the command above to create the keysotre, and you use tomcat, your server.xml file will have this section:

	<Connector port="8443" SSLEnabled="true" clientAuth="false" 
			keystoreFile="c:\dev\tools\ohad.ks" keystorePass="kspass" 
			keyAlias="alias" keystoreType="JCEKS"
			maxThreads="150" protocol="HTTP/1.1" scheme="https" 
			secure="true" sslProtocol="TLS"/>    

Java Encryption:

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec secretKey = new SecretKeySpec(key, "AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); String encryptedString = Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes())); return encryptedString;

http://techie-experience.blogspot.co.il/2012/10/encryption-and-decryption-using-aes.html http://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html#init(int, java.security.Key)

HTML forms: onSubmit vs action

Why "Secret Question" mechanism is a Bad Thing

The logic of "Secret Question" escapes me. Since the dawn of computer security we have been telling people, "DON'T make a password that is information about yourself that a hacker could discover or guess, like the name of your high school, or your favorite color. A hacker might be able to look up the name of your high school, or even if they don't know you or know anything about you, if you still live near where you went to school they might get it by tryinging local schools until they hit it. There are a small number of likely favorite colors so a hacker could guess that. Etc. Instead, a password should be a meaningless combination of letters, digits, and punctuation." But now we also tell them, "But! If you have a difficult time remembering that meaningless combination of letters, digits, and punctuation, no problem! Take some information about yourself that you can easily remember -- like the name of your high school, or your favorite color -- and you can use that as the answer to a 'security question', that is, as an alternative password."

Indeed, security questions make it even easier for the hacker than if you just chose a bad password to begin with. At least if you just used a piece of personal information for your password, a hacker wouldn't necessarily know what piece of personal information you used. Did you use the name of your dog? Your birth date? Your favorite ice cream flavor? He'd have to try all of them. But with security questions, we tell the hacker exactly what piece of personal information you used as a password!

Instead of using security questions, why don't we just say, "In case you forget your password, it is displayed on the bottom of the screen. If you're trying to hack in to someone else's account, you are absolutely forbidden from scrolling down." It would be only slightly less secure. source

Why should we NEVER use CAPTCHA

Well, here is why.

authentication-flows's People

Contributors

bitdeli-chef avatar ggmartins avatar ohadr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

authentication-flows's Issues

username is case-sensitive

MySQL works fine, but GAE' datastore does not. so the framework should support all cases and take care of this issue - convert all usernames to lowercase

description: 2 users, A@A and a@a should not be allowed.

ActivateAccountEndpoint: target HTML should be a param

the target HTML should be a param. currently it is hard ocded to
LOGIN_FORMS_DIR +"/" + "AccountActivated.htm"

when i wanna run in REST mode, i want the HTML page to be in a different dir (with the controller) so i need it to be parameterized.
'AuthenticationFailureHandler' is doing similar thing - with a param (defaultTargetUrl)

support flow : change password

2 cases: (1) after successful login, when password has expired.
(2) a link "change password" was clicked in the 'hosting' application.

support Google AppEngine !

add classes for GAE repo, and Mail Sender to auth-flows. so GAE-apps can use auth-flows package without implementing their own implementations for the above classes.

[REST] security bug: after 5 login failures, account locked but user is logged in !!

related to #35 .
the login-fail-handler is good for REST as well, since if no "redirect-uri" is defined, the parent class (SimpleUrlAuthenticationFailureHandler) does not redirect, but sends 401 instead.
However, if account is locked, i have a special treatment here, that DOES redirect. and this is a bug . So there is a need in a flag that indicates whether this is REST call, and if it is, when account is locked, instead of redirection it will return 423 (LOCKED).

loadUserByUsername(): use UsernameNotFoundException

JdbcAuthenticationAccountRepositoryImpl.loadUserByUsername(): be Spring-compatible, and use UsernameNotFoundException, and never return null.
need to change also AbstractAuthenticationAccountRepository, to catch this exception.

support REST calls (without redirects)

for example, when calling "createAccount", a RESTful does not redirect to another page. Redirecting is MVC behavior; but there are clients (AngularJS) that perform their own MVC architecture, so the auth-flows should support that hence identify REST calls (different URL?) and not redirect, but only return value.

InMemoryAuthenticationUserImpl.isCredentialsNonExpired() - be Spring!

NOTE and TODO: if i implement this method correctly, then when creds expired the login will fail (bcoz Spring calls this method and then throws CredsExpiredEception). in my flows (not sure it is the right thing), the login is successful and in the successHandler I check if password has expired.

GAE: if password expired, redirected to "set new pass" and then get exception

/setNewPassword
java.util.NoSuchElementException: No entity was found matching the key: User("[email protected]")
at com.ohadr.dictionary.gae.GAEAuthenticationAccountRepositoryImpl.changePassword(GAEAuthenticationAccountRepositoryImpl.java:200)
at com.ohadr.auth_flows.core.AuthenticationFlowsProcessorImpl.setPassword(AuthenticationFlowsProcessorImpl.java:270)
at com.ohadr.auth_flows.web.UserActionController.setNewPassword(UserActionController.java:431)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

common-crypto does not work on GAE

common-crypto does not work on GAE. because class DefaultCryptoProvider tries to store the key-store, and GAE does not allow that, jar fails to load.

create a better secured resource

the secured resource: instead of print "Hello, world" to the browser in /secured/test, show a page with logout/change-password.

exception on console, if restore-pass link was tampered with

if the link that the user got to his email was changed, an exception is shown on the browser:

HTTP Status 500 - Request processing failed; nested exception is com.ohadr.crypto.exception.CryptoException: Failed to decrypt URL content adEQ3R5utnfWr2kugM2xQ29u.rm448.ujJZtIspKvbJ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.