DHCP82 авторизация по MAC-адресу

Материал из BiTel WiKi

Перейти к: навигация, поиск

Назад

Авторизация

Нужно добавить новый тип сервиса, указать в нем галочку MAC-адрес, указать, что он дочерний к типу сервиса, который используется сейчас.

В конфигурации устройства изменить тип поиска - добавить дополнительный поиск (среди дочерних сервисов найденного сервиса первым поиском по интерфейсу - 1) по MAC-адресу - 1.

dhcp.servSearchMode=1-1

В этом режиме находится сервис абонента, затем идет поиск среди дочерних сервисов на совпадение по MAC-адресу. Если такого сервиса нет - идет ошибка авторизации MAC-адрес не найден, т.е. абонент аутентифицирован, но не авторизован. Если указаны категории IP-адресов dhcp.disable.ipCategories= , то адрес будет выдан оттуда.

Регистрация

Для автоматизации регистрации MAC-адреса абонента можно использовать скрипт на основе этого, обрабатывающего дополнительное действие (package рекомендуется поменять, например, на my.company.bgbilling.modules.inet.dyn.server). В данном скрипте привязывается только один MAC-адрес к одному дочернему сервису:

package ru.bitel.bgbilling.modules.inet.dyn.server;
 
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Date;
import java.util.List;
 
import javax.servlet.http.HttpServletRequest;
 
import org.apache.log4j.Logger;
 
import bitel.billing.common.TimeUtils;
import ru.bitel.bgbilling.common.BGException;
import ru.bitel.bgbilling.kernel.container.managed.ServerContext;
import ru.bitel.bgbilling.kernel.event.Event;
import ru.bitel.bgbilling.kernel.event.events.AdditionalActionEvent;
import ru.bitel.bgbilling.kernel.event.events.GetAdditionalWebActionListEvent;
import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetConnection;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServ;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServOption;
import ru.bitel.bgbilling.modules.inet.api.common.service.InetServService;
import ru.bitel.bgbilling.modules.inet.api.server.bean.InetConnectionDao;
import ru.bitel.bgbilling.modules.inet.api.server.bean.InetServDao;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.Utils;
import ru.bitel.common.inet.IpAddress;
import ru.bitel.common.sql.ConnectionSet;
 
/**
 * Пример обработчика дополнительного действия, привязывающий MAC-адрес к сервису Inet абонента на договоре.
 * @author amir
 */
public class MacRegisterProcessor
	extends EventScriptBase<Event>
{
	private static final Logger logger = Logger.getLogger( MacRegisterProcessor.class );
 
	private static final int actionId = 1000;
	private static final int moduleId = 4;
	private static final int servTypeId = 2;
 
	private String getAddress( final HttpServletRequest request )
	{
		// return request.getRemoteAddr();
		return request.getHeader( "X-Real-IP" );
	}
 
	@Override
	public void onEvent( final Event e, final Setup setup, final ConnectionSet connectionSet )
		throws Exception
	{
		try
		{
			if( e instanceof GetAdditionalWebActionListEvent )
			{
				final GetAdditionalWebActionListEvent ev = (GetAdditionalWebActionListEvent)e;
 
				final int contractId = ev.getContractId();
				final HttpServletRequest request = ev.getRequest();
				final String address = getAddress( request );
 
				addAction( setup, connectionSet, ev, contractId, request, address );
			}
			else if( e instanceof AdditionalActionEvent )
			{
				final AdditionalActionEvent ev = (AdditionalActionEvent)e;
				if( ev.getActionId() == actionId )
				{
					final int contractId = ev.getContractId();
					final HttpServletRequest request = ev.getRequest();
					final String address = getAddress( request );
 
					addMac( setup, connectionSet, ev, contractId, request, address );
				}
			}
		}
		catch( Exception ex )
		{
			logger.error( ex.getMessage(), ex );
		}
	}
 
	private Object[] findServ( final Connection con, final int contractId, final String address )
		throws SQLException, BGException, UnknownHostException
	{
		Object[] result = null;
 
		if( logger.isInfoEnabled() )
		{
			logger.info( "Address: " + address );
		}
 
		final InetAddress inetAddress = InetAddress.getByName( address );
 
		if( logger.isInfoEnabled() )
		{
			logger.info( "InetAddress: " + IpAddress.toString( inetAddress.getAddress() ) );
		}
 
		PreparedStatement ps = con.prepareStatement( "SELECT serv.*, connection.* FROM inet_connection_" + moduleId + " as connection"
													 + " LEFT JOIN inet_serv_" + moduleId + " as serv ON serv.id=connection.servId"
													 + " WHERE (? OR serv.contractId=?) AND connection.ipAddress=? AND connection.status=?" );
 
		ps.setBoolean( 1, contractId == -1 );
		ps.setInt( 2, contractId );
		ps.setBytes( 3, inetAddress.getAddress() );
		ps.setInt( 4, InetConnection.STATUS_ALIVE );
 
		ResultSet rs = ps.executeQuery();
		if( rs.next() )
		{
			InetServ inetServ = InetServDao.getInetServFromRS( rs, false, false );
			InetConnection inetConnection = InetConnectionDao.getConnectionFromRS( rs );
 
			result = new Object[] { inetServ, inetConnection };
		}
 
		rs.close();
		ps.close();
 
		return result;
	}
 
	private void addAction( final Setup setup, final ConnectionSet connectionSet, final GetAdditionalWebActionListEvent e, final int contractId,
							final HttpServletRequest request, final String address )
		throws Exception
	{
		final Connection con = connectionSet.getConnection();
 
		final Object[] servData = findServ( con, contractId, address );
 
		if( servData == null )
		{
			return;
		}
 
		InetServ inetServ = (InetServ)servData[0];
		// уже зарегистрирован?
		if( inetServ.getParentId() > 0 )
		{
			return;
		}
 
		InetConnection inetConnection = (InetConnection)servData[1];
 
		if( Utils.isBlankString( inetConnection.getCallingStationId() ) )
		{
			return;
		}
 
		String macAddress = InetServ.macAddressToString( InetServ.parseMacAddress( inetConnection.getCallingStationId() ) );
 
		e.addAction( actionId, "Привязать устройство " + macAddress );
	}
 
	private void addMac( final Setup setup, final ConnectionSet connectionSet, final AdditionalActionEvent e, final int contractId,
						 final HttpServletRequest request, final String address )
		throws UnknownHostException, SQLException, BGException
	{
		final Connection con = connectionSet.getConnection();
 
		final Object[] servData = findServ( con, contractId, address );
 
		if( servData == null )
		{
			return;
		}
 
		InetServ inetServ = (InetServ)servData[0];
		// уже зарегистрирован?
		if( inetServ.getParentId() > 0 )
		{
			e.addReport( "Устройство уже привязано." );
			return;
		}
 
		InetConnection inetConnection = (InetConnection)servData[1];
 
		if( Utils.isBlankString( inetConnection.getCallingStationId() ) )
		{
			return;
		}
 
		final ServerContext ctx = ServerContext.get();
		InetServService inetServService = ctx.getService( InetServService.class, moduleId );
 
		// загружаем inetServ с дочерними
		InetServ rootServ = inetServService.inetServTree( contractId );
		for( InetServ childServ : rootServ.getChildren() )
		{
			if( childServ.getId() == inetServ.getId() )
			{
				inetServ = childServ;
				break;
			}
		}
 
		addMac( setup, connectionSet, e, inetServService, contractId, inetServ, inetConnection );
	}
 
	private void addMac( final Setup setup, final ConnectionSet connectionSet, final AdditionalActionEvent e, final InetServService inetServService, final int contractId,
						 final InetServ inetServ, final InetConnection inetConnection )
		throws BGException
	{
		final byte[] macAddress = InetServ.parseMacAddress( inetConnection.getCallingStationId() );
 
		final Date now = new Date();
		InetServ childInetServ = null;
 
		if( inetServ.getChildren() != null )
		{
			for( InetServ childServ : inetServ.getChildren() )
			{
				if( !TimeUtils.dateInRange( now, childServ.getDateFrom(), childServ.getDateTo() ) )
				{
					continue;
				}
 
				childInetServ = childServ;
				break;
			}
		}
 
		List<InetServOption> inetOptionList;
 
		if( childInetServ == null )
		{
			childInetServ = new InetServ();
			childInetServ.setParentId( inetServ.getId() );
			childInetServ.setContractId( contractId );
			childInetServ.setTypeId( servTypeId );
			childInetServ.setDeviceId( inetServ.getDeviceId() );
			childInetServ.setDateFrom( new Date() );
			childInetServ.setLogin( "" );
			childInetServ.setMacAddressList( Collections.singletonList( macAddress ) );
			childInetServ.setComment( "Зарегистрирован через личный кабинет." );
 
			inetOptionList = Collections.<InetServOption> emptyList();
		}
		else
		{
			childInetServ.setMacAddressList( Collections.singletonList( macAddress ) );
 
			inetOptionList = inetServService.inetServOptionList( childInetServ.getId() );
		}
 
		inetServService.inetServUpdate( childInetServ, inetOptionList, false, false, 0 );
 
		e.addReport( "Устройство " + InetServ.macAddressToString( macAddress ) + " привязано. Необходимо выполнить переподключение." );
	}
}
Личные инструменты