How Tomcat works 10: Security

    1. 概述:
    WebApp的资源的访问限制可以通过web.xml文件来支撑。Servlet容器可以通过叫做Authenticator valve类来支持。Authenticator valve会调用context's realms的authenticate方法校验user
    2. Realm类
    (1)一个Realm通常附属于一个context, 一个container只能有一个realm【container.setRealm(realm)】
    (2)默认下,Tomcat的默认认证信息存储在tomcat-users.xml中。当然也可以使用别的认证资源,如database
    (3)Realm接口包含四个overload方法
        

public interface Realm {
            public Principal authenticate(String username, String credentials);
            public Principal authenticate(String username, byte[] credentials);
            public Principal authenticate(String username, String digest, String nonce, String nc, String cnonce, String qop, String realm, String md5a2);
            public Principal authenticate(X509Certificate cters[]);
            
            public boolean hasRole(Principal principal, String role);
        }


    
    3. GenericPrincipal:
    (1)是Principal接口的实现类
        

public class GenericPrincipal implements Principal {
        
            protected Realm realm;
            private String name;
            private String password;
            private String[] roles;
            
            public GenericPrincipal(Realm realm, String name, String password) {
                this(realm, name, password, null);
            }
            public GenericPrincipal(Realm realm, String name, String password, List<?> roles) {
                super();
                this.realm = realm;
                this.name = name;
                this.password = password;
                if(roles != null) {
                    this.roles = new String[roles.size()];
                    this.roles = (String[])roles.toArray(this.roles);
                    if(this.roles.length>0) {
                        Arrays.sort(this.roles);
                    }
                }
            }
            public boolean hasRole(String role) {
                if("*".equals(role)) {
                    return true;
                }
                if(role == null) {
                    return false;
                }
                return (Arrays.binarySearch(roles, role)>=0);
            }
            @Override
            public String getName() {        
                return name;
            }
        
        }


    
    4. LoginConfig类
    (1)包含了realm name和authentication方法authentication name必须是其中之一:BASIC,DIGEST,FORM,CLIENT-CERT
    (2)部署过程中,Tomcat启动时读取web.xml文件,若包含了login-config元素, tomcat将创建以恶LoginConfig对象
    5. Authenticator接口
    (1)代表一个认证接口,没有任何方法,仅仅是一个标记
    (2)UML
    
    6. Bootstrap:
    在启动过程中,使用context.getLoginConfig()->然后使用反射查询相应的authenticator,添加对应的valve到pipeline
    

private synchronized void authenticatorConfig() {
            SecurityConstraint constraints[] = context.findConstraints();
            if ((constraints == null) || (constraints.length == 0))
                return;
            LoginConfig loginConfig = context.getLoginConfig();
            if (loginConfig == null) {
                loginConfig = new LoginConfig("NONE", null, null, null);
                context.setLoginConfig(loginConfig);
            }
            // Has an authenticator been configured already?
            Pipeline pipeline = ((StandardContext) context).getPipeline();
            if (pipeline != null) {
                Valve basic = pipeline.getBasic();
                if ((basic != null) && (basic instanceof Authenticator))
                    return;
                Valve valves[] = pipeline.getValves();
                for (int i = 0; i < valves.length; i++) {
                    if (valves[i] instanceof Authenticator)
                        return;
                }
            } else { // no Pipeline, cannot install authenticator valve
                return;
            }
            // Has a Realm been configured for us to authenticate against?
            if (context.getRealm() == null) {
                return;
            }
            // Identify the class name of the Valve we should configure
            String authenticatorName = "org.apache.catalina.authenticator.BasicAuthenticator";
            // Instantiate and install an Authenticator of the requested class
            Valve authenticator = null;
            try {
                Class authenticatorClass = Class.forName(authenticatorName);
                authenticator = (Valve) authenticatorClass.newInstance();
                ((StandardContext) context).addValve(authenticator);
                System.out.println("Added authenticator valve to Context");
            } catch (Throwable t) {
    
            }
        }


    
    
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值