Package org.jboss.errai.persistence.server.security

Source Code of org.jboss.errai.persistence.server.security.HibernateAuthenticationAdapter

/*
* Copyright 2009 JBoss, a divison Red Hat, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jboss.errai.persistence.server.security;

import com.google.inject.Inject;
import com.google.inject.Provider;
import org.hibernate.Session;
import org.jboss.errai.bus.client.api.Message;
import org.jboss.errai.bus.client.framework.MessageBus;
import org.jboss.errai.bus.client.protocols.SecurityCommands;
import org.jboss.errai.bus.client.protocols.SecurityParts;
import org.jboss.errai.bus.client.security.CredentialTypes;
import org.jboss.errai.bus.server.ErraiBootstrapFailure;
import org.jboss.errai.bus.server.QueueSession;
import org.jboss.errai.bus.server.security.auth.AuthSubject;
import org.jboss.errai.bus.server.security.auth.AuthenticationAdapter;
import org.jboss.errai.bus.server.security.auth.AuthenticationFailedException;
import org.jboss.errai.bus.server.security.auth.SimpleRole;
import org.jboss.errai.bus.server.service.ErraiService;
import org.jboss.errai.bus.server.service.ErraiServiceConfigurator;
import org.jboss.errai.bus.server.util.ConfigUtil;
import org.jboss.errai.bus.server.util.ConfigVisitor;
import org.jboss.errai.persistence.server.security.annotations.AuthPasswordField;
import org.jboss.errai.persistence.server.security.annotations.AuthRolesField;
import org.jboss.errai.persistence.server.security.annotations.AuthUserEntity;
import org.jboss.errai.persistence.server.security.annotations.AuthUsernameField;
import org.mvel2.MVEL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import static org.jboss.errai.bus.client.api.base.MessageBuilder.createConversation;

public class HibernateAuthenticationAdapter implements AuthenticationAdapter {
    private ErraiServiceConfigurator configurator;
    private MessageBus bus;

    private Class userEntity;
    private String userField;
    private String passworldField;
    private String rolesField;

    private String challengeQueryString;

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Inject
    public HibernateAuthenticationAdapter(ErraiServiceConfigurator configurator, MessageBus bus) {
        log.info("initializing.");
        this.configurator = configurator;
        this.bus = bus;

        ConfigUtil.visitAllTargets(configurator.getConfigurationRoots(),
                new ConfigVisitor() {
                    public void visit(Class<?> clazz) {
                        if (clazz.isAnnotationPresent(AuthUserEntity.class)) {
                            if (userEntity != null) {
                                throw new ErraiBootstrapFailure("More than one @AuthUserEntity defined in classpath (" + userEntity.getName() + " and " + clazz.getName() + " cannot co-exist)");
                            }

                            userEntity = clazz;
                            for (Field f : clazz.getDeclaredFields()) {
                                if (f.isAnnotationPresent(AuthUsernameField.class)) {
                                    if (f.getType() != String.class) {
                                        throw new ErraiBootstrapFailure("@AuthUsernameField must annotated a String field");
                                    }
                                    userField = f.getName();
                                } else if (f.isAnnotationPresent(AuthPasswordField.class)) {
                                    if (f.getType() != String.class) {
                                        System.out.println("Stopping B");
                                        throw new ErraiBootstrapFailure("@AuthPasswordField must annotated a String field");
                                    }
                                    passworldField = f.getName();
                                } else if (f.isAnnotationPresent(AuthRolesField.class)) {
                                    rolesField = f.getName();
                                }
                            }
                        }
                    }
                });


        if (userEntity == null) {
            throw new RuntimeException("You have not specified a @AuthUserEntity for the hibernate security extension.");
        } else if (userField == null) {
            throw new RuntimeException("You must specify a @AuthUsernameField in the '" + userEntity.getName() + "' entity.");
        } else if (passworldField == null) {
            throw new RuntimeException("You must specify a @AuthPasswordField in the '" + userEntity.getName() + "' entity.");
        } else if (rolesField == null) {
            throw new RuntimeException("You must specify a @AuthRolesField in the '" + userEntity.getName() + "' entity.");
        }

        log.info("configured authentication entity: " + userEntity.getName());

        challengeQueryString = "from " + userEntity.getSimpleName() + " a where a." + userField + "=:name and "
                + " a." + passworldField + "=:password";

        log.info("challenge query string: " + challengeQueryString);
    }

    public void challenge(Message message) {
        Session session = ((Provider<Session>) message.getResource(Provider.class, "SessionProvider")).get();
        final String name = message.get(String.class, SecurityParts.Name);
        final String password = message.get(String.class, SecurityParts.Password);

        Object userObj = session.createQuery(challengeQueryString)
                .setString("name", name)
                .setString("password", password)
                .uniqueResult();

        if (userObj != null) {
            AuthSubject authSubject = new AuthSubject(name, name, (Collection) MVEL.getProperty(rolesField, userObj));

            /**
             * If we got this far, then the authentication succeeded. So grab access to the HTTPSession and
             * add the authorization token.
             */
            addAuthenticationToken(message, authSubject);


            /**
             * Prepare to send a message back to the client, informing it that a successful login has
             * been performed.
             */
            createConversation(message)
                    .subjectProvided()
                    .command(SecurityCommands.SuccessfulAuth)
                    .with(SecurityParts.Roles, authSubject.toRolesString())
                    .with(SecurityParts.Name, name)
                    .noErrorHandling()
                    .sendNowWith(bus);
        } else {
            /**
             * The login failed. How upsetting. Life must go on, and we must inform the client of the
             * unfortunate news.
             */
            createConversation(message)
                    .subjectProvided()
                    .command(SecurityCommands.FailedAuth)
                    .with(SecurityParts.Name, name)
                    .noErrorHandling().sendNowWith(bus);

            throw new AuthenticationFailedException();
        }

    }

    private void addAuthenticationToken(Message message, AuthSubject loginSubject) {
        message.getResource(QueueSession.class, "Session").setAttribute(ErraiService.SESSION_AUTH_DATA, loginSubject);
    }

    public boolean isAuthenticated(Message message) {
        return message.hasResource("Session") && message.getResource(QueueSession.class, "Session").hasAttribute(ErraiService.SESSION_AUTH_DATA);
    }

    public boolean endSession(Message message) {
        boolean sessionEnded = isAuthenticated(message);
        if (sessionEnded) {
            getAuthDescriptor(message).remove(new SimpleRole(CredentialTypes.Authenticated.name()));
            message.getResource(QueueSession.class, "Session").removeAttribute(ErraiService.SESSION_AUTH_DATA);
            return true;
        } else {
            return false;
        }
    }

    private Set getAuthDescriptor(Message message) {
        Set credentials = message.get(Set.class, SecurityParts.Credentials);
        if (credentials == null) {
            message.set(SecurityParts.Credentials, credentials = new HashSet());
        }
        return credentials;
    }

    public void process(Message message) {

    }
}
TOP

Related Classes of org.jboss.errai.persistence.server.security.HibernateAuthenticationAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.