net.maritimecloud.portal.infrastructure.security.shiro.MaritimeCloudIdentityRealm.java Source code

Java tutorial

Introduction

Here is the source code for net.maritimecloud.portal.infrastructure.security.shiro.MaritimeCloudIdentityRealm.java

Source

/* Copyright 2014 Danish Maritime Authority.
 *
 *  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 net.maritimecloud.portal.infrastructure.security.shiro;

import net.maritimecloud.identityregistry.domain.Identity;
import net.maritimecloud.identityregistry.domain.IdentityService;
import net.maritimecloud.identityregistry.domain.EncryptionService;
import net.maritimecloud.portal.application.ApplicationServiceRegistry;
import net.maritimecloud.identityregistry.domain.Role;
import net.maritimecloud.portal.infrastructure.service.SHA512EncryptionService;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

/**
 * Implementation of the Shiro Realm integrating into the MaritimeCloud identity repository.
 * <p>
 * The users in this realm uses password encryption. Shiro configuration (shiro.ini) must match this encryption algorithm.
 * <p>
 * @author Christoffer Brrild
 * @see EncryptionService
 * @see SHA512EncryptionService
 */
public class MaritimeCloudIdentityRealm extends AuthorizingRealm {

    public static final String REALM = "MaritimeCloudIdentityRealm";

    public MaritimeCloudIdentityRealm() {
        setName(REALM); // This name must match the name in the User class's getPrincipals() method
    }

    private IdentityService identityService() {
        return ApplicationServiceRegistry.identityService();
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {

        if (authenticationToken instanceof UsernamePasswordToken) {
            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
            String username = usernamePasswordToken.getUsername();
            char[] password = usernamePasswordToken.getPassword();

            if (username == null || username.isEmpty()) {
                throw new AccountException("Null and empty usernames are not allowed by this realm!");
            }
            if (password == null || password.length == 0) {
                throw new AccountException("Null and empty passwords are not allowed by this realm!");
            }

            // Lookup user
            Identity identity = identityService().findActivatedIdentityByUsername(username);

            if (identity == null) {
                throw new UnknownAccountException("Could not authenticate with given credentials");
            }

            // Create Auth Info
            return new SimpleAuthenticationInfo(identity.userId().identifier(), identity.encryptedPassword(),
                    ByteSource.Util.bytes("salt"), // (not sure if this salt is used at all?)
                    getName());
        } else {
            return null;
        }
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        // Get the userId from the first principal in the collection
        String userIdentifier = (String) getAvailablePrincipal(principals);

        // Lookup user
        Identity identity = identityService().findByUserId(userIdentifier);
        assertUserFound(identity);

        // Add roles to AuthorizationInfo
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(Role.USER.name());
        if (identity.username().equalsIgnoreCase("admin")) {
            info.addRole(Role.ADMIN.name());
        }
        //user.userRoles().all().stream().forEach((role) -> {
        //    info.addRole(role.name());
        //});

        return info;
    }

    private void assertUserFound(Identity user) {
        if (user == null) {
            throw new UnknownAccountException("No user found in application registry");
        }
    }

}