How Tomcat works 10: Security类

本文深入探讨了Tomcat中的认证机制,包括web.xml文件如何用于限制WebApp资源访问,Authenticatorvalve的作用,Realm类的功能及其与Principal的关系,以及LoginConfig类如何配置认证方式。

    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) {
	
			}
		}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值