/* * Copyright (C) 2014 GG-Net GmbH - Oliver Günther * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package eu.ggnet.dwoss.rights.op; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; import javax.ejb.Stateless; import javax.enterprise.inject.Instance; import javax.inject.Inject; import javax.persistence.EntityManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.ggnet.dwoss.rights.api.AtomicRight; import eu.ggnet.dwoss.rights.api.AuthenticationService; import eu.ggnet.dwoss.rights.assist.Rights; import eu.ggnet.dwoss.rights.entity.Operator; import eu.ggnet.dwoss.util.UserInfoException; /** * * @author Bastian Venz */ @Stateless public class AuthenticationBean implements Authentication { private static final Logger L = LoggerFactory.getLogger(AuthenticationBean.class); @Inject @Rights EntityManager rightsEm; @Inject Instance<AuthenticationService> service; /** * This method returns a {@link Set} of {@link AtomicRight}'s when the {@link Operator} is authorized or throw a {@link UserInfoException} when username * and/or password is wrong. * <p> * @param username the username of the {@link Operator}. * @param password the password of the {@link Operator}. * @return {@link Operator} with {@link AtomicRight}'s when the {@link Operator} is authorized. * @throws UserInfoException is thrown when username and/or password is wrong. */ @Override public eu.ggnet.dwoss.rights.api.Operator login(String username, char[] password) throws UserInfoException { //find users by Usernmae List<Operator> result = rightsEm.createNamedQuery("Operator.byUsername", Operator.class).setParameter(1, username).getResultList(); if ( result.isEmpty() ) throw new UserInfoException("User " + username + " ist noch nicht angelegt"); Operator op = result.get(0); if ( !service.isAmbiguous() && !service.isUnsatisfied() ) { if ( service.get().authenticate(username, password) ) return op.toDto(); } else { if ( op.getPassword() != null && op.getSalt() != null && Arrays.equals(op.getPassword(), hashPassword(password, op.getSalt())) ) return op.toDto(); } throw new UserInfoException("Authentifizierung nicht gelungen!"); } /** * This hash the given password with the given salt. * <p> * @param password is the readable Password. * @param salt is the Salt that will used to salt the password. * @return return the hashed and salted password. */ private static byte[] hashPassword(char[] password, byte[] salt) { StringBuilder sb = new StringBuilder(); try { byte[] pwBytes = new String(password).getBytes("UTF-8"); MessageDigest md = MessageDigest.getInstance("SHA-512"); md.update(salt); byte[] bytes = md.digest(pwBytes); for (int i = 0; i < bytes.length; i++) { sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); } return sb.toString().getBytes("UTF-8"); } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { throw new RuntimeException(); } } }