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 ) + " привязано. Необходимо выполнить переподключение." ); } }