com.jythonui.server.security.impl.SubjectCache.java Source code

Java tutorial

Introduction

Here is the source code for com.jythonui.server.security.impl.SubjectCache.java

Source

/*
 * Copyright 2017 stanislawbartkowski@gmail.com  
 * 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 com.jythonui.server.security.impl;

import java.util.UUID;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;

import com.jythonui.server.IStorageMemCache;
import com.jythonui.server.UtilHelper;
import com.jythonui.server.getmess.IGetLogMess;
import com.jythonui.server.holder.Holder;
import com.jythonui.server.logmess.IErrorCode;
import com.jythonui.server.logmess.ILogMess;
import com.jythonui.server.security.token.ICustomSecurity;
import com.jythonui.server.security.token.PasswordSecurityToken;

class SubjectCache extends UtilHelper {

    private final IStorageMemCache iCache;
    private final IGetLogMess gMess;

    class CurrentSubject {
        SessionEntry se;
        SecurityManager sManager;
        Subject currentUser;
    }

    private static ThreadLocal<CurrentSubject> lastS = new ThreadLocal<CurrentSubject>();

    SubjectCache(IStorageMemCache iCache, IGetLogMess gMess) {
        this.iCache = iCache;
        this.gMess = gMess;
    }

    private static SecurityManager constructManager(String realm) {
        info(Holder.getM().getMessN(ILogMess.REALMINITIALZATION, realm));
        Factory<SecurityManager> factory = new IniSecurityManagerFactory(realm);
        SecurityManager securityManager = factory.getInstance();
        return securityManager;
    }

    private class Result {
        Subject sub;
        String tokenS;

        Result(Subject sub, String tokenS) {
            this.sub = sub;
            this.tokenS = tokenS;
        }
    }

    private static Subject buildSubject() {
        Subject currentUser = new Subject.Builder().buildSubject();
        return currentUser;
    }

    private Result authenticate(SessionEntry se, String tokenS) {
        SecurityManager securityManager = constructManager(se.getRealm());
        SecurityUtils.setSecurityManager(securityManager);
        Subject currentUser = buildSubject();
        PasswordSecurityToken token = new PasswordSecurityToken(se.getUser(), se.getPassword(), se.getiCustom());
        info(gMess.getMessN(ILogMess.AUTHENTICATEUSER, se.getUser(), se.getRealm()));
        try {
            currentUser.login(token);
        } catch (UnknownAccountException uae) {
            info(gMess.getMess(IErrorCode.ERRORCODE3, ILogMess.AUTHENTICATENOUSER, se.getUser()));
            return null;
        } catch (IncorrectCredentialsException ice) {
            info(gMess.getMess(IErrorCode.ERRORCODE4, ILogMess.AUTHENTICATEINCORECTPASSWORD, se.getUser()));
            return null;
        } catch (LockedAccountException lae) {
            info(gMess.getMess(IErrorCode.ERRORCODE5, ILogMess.AUTHENTOCATELOCKED, se.getUser()));
            return null;
        } catch (AuthenticationException ae) {
            severe(gMess.getMess(IErrorCode.ERRORCODE6, ILogMess.AUTHENTICATEOTHERERROR, se.getUser(),
                    ae.getMessage()), ae);
            ae.printStackTrace();
            return null;
        } catch (UnknownSessionException ae) {
            info(gMess.getMess(IErrorCode.ERRORCODE22, ILogMess.AUTHENTICATEOTHERERROR, se.getUser(),
                    ae.getMessage()));
            return null;
        }

        info(gMess.getMessN(ILogMess.OKAUTHENTICATED));
        if (tokenS == null) {
            UUID i = UUID.randomUUID();
            tokenS = i.toString();
            iCache.put(tokenS, se);
        }
        CurrentSubject subS = new CurrentSubject();
        subS.se = se;
        subS.sManager = securityManager;
        subS.currentUser = currentUser;
        lastS.set(subS);
        return new Result(currentUser, tokenS);
    }

    String authenticateS(SessionEntry se) {
        Result res = authenticate(se, null);
        if (res == null)
            return null;
        return res.tokenS;
    }

    private SessionEntry get(String token) {
        SessionEntry e = null;
        e = (SessionEntry) iCache.get(token);
        if (e == null) {
            info(token + " token not found ");
        }
        return e;
    }

    boolean validToken(String token) {
        return get(token) != null;
    }

    ICustomSecurity getCustom(String token) {
        SessionEntry se = get(token);
        if (se == null) // TODO: more verbose log
            return null;
        return se.getiCustom();
    }

    boolean isAutenticated(String token) {
        SessionEntry se = get(token);
        return se.isAuthenticate();
    }

    String getUserName(String token) {
        SessionEntry se = get(token);
        if (se == null) // TODO: more verbose log
            return null;
        return se.getUser();
    }

    Subject getSubject(String token) {
        SessionEntry se = get(token);
        if (se == null)
            return null; // TODO: more detailed log
        CurrentSubject subC = lastS.get();
        if (subC != null && se.eq(subC.se)) {
            // SecurityUtils.setSecurityManager(subC.sManager);
            // Subject sub = SecurityUtils.getSubject();
            // Subject sub = buildSubject();
            return subC.currentUser;
        }
        // validate again
        info("Authenticate again");
        Result res = authenticate(se, token);
        if (res == null) {
            severe(gMess.getMess(IErrorCode.ERRORCODE23, ILogMess.CANNOTAUTHENTICATEAGAIN, se.getUser(),
                    se.getRealm()));
            return null;
        }
        return res.sub;
    }

    void removeSubject(String token) {
        iCache.remove(token);
        lastS.remove();
    }

}